首先,当你这样做时:
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()
尽管常见的风格实践,强制转换to的返回值(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;
}