首先,当你这样做:
num = "123056";
你没有复制字符串“123056”堆由malloc()
分配的区域。在C语言中,分配char *
指针字符串文本值等同于设置它为一个常数 - 即等同于:
char str[] = "123056";
所以,你刚刚完成有你放弃了你的唯一参考由malloc()
分配的100字节堆区域,这就是为什么您的后续代码不能打印正确的值; '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';
...,避免迭代指针,通过deferencing如下:
*(p + 3) = '4';
其他一些注意事项:
虽然常见文体练习中,将malloc()
的返回值转换为(char *)
是不必要的。 C语言保证了void *
类型的转换和对齐。
总是检查返回值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;
}
的可能的复制[为什么写有“字符\ * S”,而不是“char形式\ [\]”初始化字符串时,我得到一个分段错误? ](http://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-string-initialized-with-cha) – jww 2016-10-20 11:07:51