Прежде всего, когда вы делаете:
num = "123056";
Вы не копируете строку «123056» в область кучи, выделенную malloc()
. В C присвоение указателю char *
строкового литерала равнозначно установке его в качестве константы, то есть идентично:
char str[] = "123056";
Итак, то, что вы только что достигли, это то, что вы отказались от своей единственной ссылки на область кучи размером 100 байт, выделенную malloc()
, поэтому ваш следующий код не выводит правильное значение; «p
» по-прежнему указывает на область кучи, выделенную malloc()
(поскольку num
указывает на нее во время назначения), но num
больше не делает.
Я предполагаю, что вы на самом деле намеревались скопировать строку "123056" в эту область кучи. Вот как это сделать:
strcpy(num, "123056");
Хотя, это лучшая практика по ряду причин:
strncpy(num, "123056", 100 - 1); /* leave room for \0 (null) terminator */
Если вы только что сделали:
#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;
}
Вы бы получили правильный результат:
123456
Вы можете заключить эту операцию:
p = p + 3;
*p = '4';
... и избегайте итерации указателя, ссылаясь следующим образом:
*(p + 3) = '4';
Несколько других заметок:
Хотя обычная стилистическая практика, приведение возвращаемого значения от malloc()
к (char *)
не является необходимым. Преобразование и выравнивание типа void *
гарантируется языком C.
ВСЕГДА проверяйте возвращаемое значение malloc()
. Это будет NULL, если выделение кучи не удалось (т. Е. У вас недостаточно памяти), и в этот момент ваша программа должна завершиться.
В зависимости от реализации область памяти, выделенная malloc()
, может содержать устаревший мусор в определенных ситуациях. Всегда полезно обнулять его после выделения:
memset(num, 0, 100);
Никогда не забывайте free()
свою кучу! В этом случае программа закроется, и ОС очистит ваш мусор, но если вы не освоитесь, у вас мгновенно возникнут утечки памяти.
Итак, вот «лучшая практика» версия:
#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;
}