首先,当您执行以下操作时:
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';
...并避免迭代指针,通过以下方式解除引用:
*(p + 3) = '4';
一些其他的注意事项:
Although common stylistic practice, casting the return value of malloc()
to (char *)
is unnecessary. Conversion and alignment of the void *
type is guaranteed by the C language.
ALWAYS check the return value of malloc()
. It will be NULL if the heap allocation failed (i.e. you're out of memory), and at that point your program should exit.
Depending on the implementation, the area of memory allocated by malloc()
may contain stale garbage in certain situations. It is always a good idea to zero it out after allocation:
memset(num, 0, 100);
Never forget to free()
your heap! In this case, the program will exit and the OS will clean up your garbage, but if you don't get into the habit, you will have memory leaks in no time.
所以,以下是“最佳实践”版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *num, *p;
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;
}