You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

指针与指针数组理解误区:为何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;
}

总结一下你之前的误区

  1. 把指针地址的赋值当成了字符串内容的复制,导致所有指针指向同一块内存。
  2. 没有意识到指针数组的每个元素需要指向独立的内存区域,才能存储不同的数据。
  3. 内存分配的大小没有考虑字符串结束符,且只分配了一块内存,无法存储多个独立的字符串。

内容的提问来源于stack exchange,提问作者A.I

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 15:38:15