En primer lugar, cuando lo hace:
num = "123056";
No está copiando la cadena "123056" a la zona del montón asignado por malloc()
. En C, la asignación de un puntero char *
un valor literal de cadena es equivalente a establecer como una constante - es decir, idéntica a:
char str[] = "123056";
Por lo tanto, lo que acaba has logrado no has abandonado su única referencia a la Área de almacenamiento de 100 bytes asignada por malloc()
, por lo que su código posterior no imprime el valor correcto; 'p
' todavía apunta al área de pila asignada por malloc()
(ya que num
lo señaló en el momento de la asignación), pero num
ya no lo hace.
Supongo que en realidad tenía la intención de hacer era copiar la cadena "123056" en esa área del montón. He aquí cómo hacerlo:
strcpy(num, "123056");
Aunque, esto es mejor práctica para una variedad de razones:
strncpy(num, "123056", 100 - 1); /* leave room for \0 (null) terminator */
Si acababa de hacer:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *num = malloc(100);
char *p = num;
strncpy(num, "123056", 100 - 1);
p = p + 3;
*p = '4';
printf("%s\n", num);
return 0;
}
Usted habría conseguido la resultado correcto:
123456
Usted puede contraer esta operación:
p = p + 3;
*p = '4';
... y evitar la iteración del puntero, por deferencing de la siguiente manera:
*(p + 3) = '4';
Algunas otras notas:
Aunque estilística común práctica, arrojar el valor de retorno de malloc()
a (char *)
es innecesario. La conversión y alineación del tipo void *
está garantizada por el lenguaje C.
SIEMPRE verifique el valor de retorno de malloc()
. Será NULO si la asignación del montón falló (es decir, no tiene memoria) y en ese punto su programa debería salir.
Dependiendo de la implementación, el área de memoria asignada por malloc()
puede contener basura obsoleta en ciertas situaciones.Siempre es una buena idea para poner a cero a cabo después de la asignación:
memset(num, 0, 100);
nunca se olvide de free()
su montón! En este caso, el programa se cerrará y el sistema operativo limpiará su basura, pero si no adquiere el hábito, tendrá pérdidas de memoria en muy poco tiempo.
Por lo tanto, aquí está la "mejor práctica" versión:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *num, *p;
/*
* Don't take 1-byte chars for granted - good habit to get into.
*/
num = malloc(sizeof(char) * 100);
if(num == NULL)
exit(1);
memset(num, 0, sizeof(char) * 100);
p = num;
strncpy(num, "123056", 100 - 1);
*(p + 3) = '4';
printf("%s\n", num);
free(num);
return 0;
}
duplicado posible de [¿Por qué aparece un fallo de segmentación al escribir a una cadena inicializado con "char \ * s", pero no "char s \ [\]"? ] (http://stackoverflow.com/questions/164194/why-do-i-get-asegmentation-fault-when-writing-to-a-string-initialized-with-cha) – jww