operadores - punteros en c
¿Por qué este programa en C que desreferencia un área de memoria con alias causa un error de segmentación? (2)
¿Puedes decir conceptualmente cuál es el problema? Si desreferencia un puntero a la memoria, ¿qué causa esto?
Cuando tiene una ranura %s
en la cadena de formato, printf
espera ver un char*
como el argumento correspondiente. Es por eso que debe pasar myptr2
(que es la dirección de ''A''
y de la cual se pueden deducir las direcciones posteriores de los caracteres de cadena).
Si pasa *myptr2
en *myptr2
lugar, básicamente está pasando el caracter ''A''
sí (sin información alguna sobre dónde está esa ''A''
particular, lo que hubiera permitido a printf
leer el resto de la cadena). En pocas palabras, printf
espera un puntero allí, por lo que intenta tratar el argumento correspondiente como un puntero.
Ahora observe que el carácter que aprobó (al quitarle una referencia a un char*
, por lo tanto obtener un char
con el valor de ''A''
) tiene un tamaño de 1 byte, mientras que un puntero tiene un tamaño de 4 u 8 bytes típicamente. Esto significa que printf
probablemente leerá una dirección de basura compuesta de un carácter y algunos datos aleatorios encontrados en la pila. No puede haber garantías sobre lo que puede sucederle al programa en este caso, por lo que todo el incidente invoca un comportamiento indefinido.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *myptr = calloc(500,1);
char *myptr2 = myptr;
*myptr++ = ''A'';
*myptr++ = ''B'';
*myptr = ''/0'';
/* This should dereference the beginning of the memory and print until myptr[2] which is ''/0'' */
printf("Myptr2 points to: %s/n", *myptr2);
free(myptr);
return(EXIT_SUCCESS);
}
¿Por qué la línea 13 (la línea printf) crea un SIGSEV? Debería estar apuntando al comienzo de la memoria y luego printf debería imprimir hasta que llegue al ''/ 0''.
En su código, no debe desreferenciar myptr2 en el segundo argumento de printf:
printf("Myptr2 points to: %s/n", *myptr2);
con:
printf("Myptr2 points to: %s/n", myptr2);
Al usar% s con printf, debe dar al puntero el primer carácter de la cadena.