C语言中字符指针数组存储用户输入时字符串被覆盖的原因
为什么输入多个名字后输出全是最后一个?
咱们先拆解你代码里的问题,就能明白为啥会出现这种情况了:
核心问题:所有指针都指向了同一个内存地址
你看这段代码:
names[i] = (char *)malloc(strlen(name)); names[i] = &name;
第一行你给names[i]分配了一块内存,但第二行直接把names[i]重新赋值成了局部数组name的地址——等于之前的malloc完全白做了,还造成了内存泄漏。
更关键的是:整个循环里,你每次输入的名字都会覆盖name数组里的内容,而names数组里的所有元素都指向了同一个name数组的地址。当循环结束时,name里存的是最后一次输入的"Andrew",所以打印的时候所有指针指向的都是这块内存,自然输出全是Andrew。
为什么用strcpy就正常?
当你用strcpy(names[i], name)的时候,是把name数组里的内容复制到了你之前malloc分配的那块独立内存里。每个names[i]指向的都是自己的内存块,各自存着每次输入的名字,所以打印的时候就能正确显示每个不同的名字了。
还要注意一个小坑:malloc的内存大小
另外你malloc的时候只给了strlen(name)的空间,但C语言里字符串是以\0结尾的,strlen不会算上这个终止符,所以正确的malloc应该是:
names[i] = malloc(strlen(name) + 1); // 多分配1个字节存'\0'
(另外C里malloc返回的是void*,不需要强制转成char*,这是个小细节)
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { char *names[3]; char name[20]; int i; for(i = 0; i < 3; i++) { printf("Enter your name\n"); scanf("%s", name); // 分配足够的内存,包括终止符 names[i] = malloc(strlen(name) + 1); // 复制字符串到分配的内存 strcpy(names[i], name); } printf("Printing the names\n"); for(i = 0; i < 3; i++) { printf("%s\n", names[i]); // 记得用完内存要释放,避免泄漏 free(names[i]); } return 0; }
内容的提问来源于stack exchange,提问作者redixhumayun
相关产品推荐
相关产品推荐

