指针与指针数组理解误区:为何C程序输出重复内容?
你遇到的指针数组误区解析
嘿,这个问题其实是初学者刚接触指针时很容易踩的坑,我来帮你理清楚到底哪里出问题了~
核心问题:所有指针都指向同一块内存
你现在的代码里,passer是一个指针数组没错,但你把数组里的每一个元素都赋值成了同一个department_id的地址。也就是说,passer[0]、passer[1]……全指向同一块用malloc(8)分配的内存区域。
每次调用scanf("%s", department_id)的时候,都会把新输入的字符串覆盖到这块内存里。所以最后不管你看数组里的哪个元素,它们指向的都是最后一次输入的内容——也就是world,自然输出两次world啦。
你混淆的两个关键概念
这里的核心误区是没搞清楚指针赋值和字符串复制的区别:
passer[i] = department_id;这行代码做的不是复制字符串内容,只是把department_id这个指针里存的内存地址,复制给了passer[i]。相当于让数组里的每个指针都“指着”同一个地方。- 你需要的是复制字符串本身,而不是复制指针的地址。这意味着每个部门ID都需要有自己独立的内存空间来存储。
另外还有个小问题:你用malloc(8)只分配了8字节的内存,如果用户输入的字符串长度超过7(因为字符串末尾要存\0),就会发生缓冲区溢出,这是很危险的哦。
怎么修改才能得到正确结果?
有两种常见的解决方式,我给你分别说一下:
方式1:为每个ID分配独立内存(推荐,灵活)
每次循环时,先读取输入到临时缓冲区,然后为当前ID分配足够的内存,再把字符串复制过去。这样每个passer[i]都会指向一块独立的内存,存储各自的ID:
#include <stdio.h> #include <stdlib.h> #include <string.h> void string_array(char *array[], size_t length) { int i ; for (i = 0; i < length; i++) { printf("\n%s\n", array[i]); } } int main(){ int i, department_quantity; char *passer[8]; char temp_id[20]; // 临时存输入,避免内存分配过小 printf("Enter number of departments:"); scanf("%d", &department_quantity); // 清空输入缓冲区的换行,避免影响后续scanf while(getchar() != '\n'); for(i = 0; i < department_quantity; i++){ printf("Enter ID of department #%d\n", i + 1); scanf("%19s", temp_id); // 限制输入长度,防止溢出 // 为当前ID分配内存:字符串长度+1(存结束符'\0') passer[i] = malloc(strlen(temp_id) + 1); if(passer[i] == NULL){ // 检查内存分配是否成功 perror("Failed to allocate memory"); exit(EXIT_FAILURE); } strcpy(passer[i], temp_id); // 把临时缓冲区的字符串复制到新内存 } string_array(passer, department_quantity); // 记得释放内存,避免内存泄漏 for(i = 0; i < department_quantity; i++){ free(passer[i]); } return 0; }
方式2:用二维字符数组(简单,但长度固定)
如果确定部门ID的长度不会超过某个值,也可以直接声明一个二维字符数组,这样每个元素都是独立的字符数组,天然存不同的内容:
#include <stdio.h> #include <string.h> void string_array(char array[][20], size_t length) { int i ; for (i = 0; i < length; i++) { printf("\n%s\n", array[i]); } } int main(){ int i, department_quantity; char passer[8][20]; // 最多8个部门,每个ID最长19字符 printf("Enter number of departments:"); scanf("%d", &department_quantity); while(getchar() != '\n'); for(i = 0; i < department_quantity; i++){ printf("Enter ID of department #%d\n", i + 1); scanf("%19s", passer[i]); } string_array(passer, department_quantity); return 0; }
总结一下你之前的误区
- 把指针地址的赋值当成了字符串内容的复制,导致所有指针指向同一块内存。
- 没有意识到指针数组的每个元素需要指向独立的内存区域,才能存储不同的数据。
- 内存分配的大小没有考虑字符串结束符,且只分配了一块内存,无法存储多个独立的字符串。
内容的提问来源于stack exchange,提问作者A.I
相关产品推荐
相关产品推荐

