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

指针使用问题:向动态分配数组读取数据仅最后条目显示异常求助

嘿,这问题我太熟了!十有八九是你把所有数组元素都指向了同一块内存区域——这可是动态数组处理字符串时的经典踩坑点!

先给你还原一下最常见的错误代码场景(应该和你的情况八九不离十):

#include <stdio.h>
#include <stdlib.h>

int main() {
    int count = 3;
    char** arr = malloc(count * sizeof(char*));
    char temp_buf[100]; // 固定的栈内存缓冲区

    for (int i = 0; i < count; i++) {
        printf("输入第%d条内容:", i+1);
        scanf("%s", temp_buf);
        arr[i] = temp_buf; // 所有元素都存了同一个缓冲区的地址
    }

    // 输出时全是最后一条输入
    for (int i = 0; i < count; i++) {
        printf("arr[%d] = %s\n", i, arr[i]);
    }
    free(arr);
    return 0;
}

问题根源

你循环里的temp_buf是同一块栈内存,每次输入都会覆盖这块内存里的内容。而你只是把这块内存的地址赋值给arr[i],结果数组里所有元素都指向同一个地方——最后一次输入自然就把之前的内容全盖住了,输出时当然全是最后一条。

解决办法:为每个字符串单独分配内存

给你两种靠谱的实现方案:

方案1:手动分配内存+复制内容

适合用scanf/fgets读取的场景:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    int count = 3;
    char** arr = malloc(count * sizeof(char*));
    char temp_buf[100];

    for (int i = 0; i < count; i++) {
        printf("输入第%d条内容:", i+1);
        scanf("%s", temp_buf);
        
        // 为当前字符串分配足够内存(+1是给字符串终止符'\0'留位置)
        arr[i] = malloc(strlen(temp_buf) + 1);
        if (arr[i] == NULL) { // 千万别忘了检查内存分配是否成功
            perror("内存分配失败");
            return 1;
        }
        strcpy(arr[i], temp_buf); // 把输入内容复制到新内存里
    }

    // 输出测试
    for (int i = 0; i < count; i++) {
        printf("arr[%d] = %s\n", i, arr[i]);
        free(arr[i]); // 先逐个释放每个字符串的内存
    }
    free(arr); // 最后释放数组本身
    return 0;
}

方案2:用getline自动分配内存(更安全,支持带空格的输入)

如果你的输入需要包含空格,scanf("%s")会在空格处截断,用getline更合适:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int count = 3;
    char** arr = malloc(count * sizeof(char*));
    size_t buf_len = 0;

    for (int i = 0; i < count; i++) {
        printf("输入第%d条内容:", i+1);
        // getline会自动分配足够的内存,直接存在arr[i]里
        ssize_t read_len = getline(&arr[i], &buf_len, stdin);
        if (read_len == -1) {
            perror("读取输入失败");
            return 1;
        }
        // 可选:去掉getline读取到的换行符
        if (arr[i][read_len-1] == '\n') {
            arr[i][read_len-1] = '\0';
        }
    }

    // 输出测试
    for (int i = 0; i < count; i++) {
        printf("arr[%d] = %s\n", i, arr[i]);
        free(arr[i]);
    }
    free(arr);
    return 0;
}

额外提醒

  1. 内存分配后一定要检查返回值是否为NULL,避免内存不足导致程序崩溃;
  2. 动态分配的内存要记得释放,先释放每个字符串,再释放数组本身,防止内存泄漏;
  3. 如果需要读取带空格的输入,别用scanf("%s"),改用fgets或getline。

内容的提问来源于stack exchange,提问作者Corey Shouse

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:34:52