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

如何将字符串复制到动态二维数组?代码问题排查

可行,但你的代码存在多个严重问题

首先明确:通过getchar()流式读取输入并存储到二维字符串数组是完全可行的,但你的代码有不少致命bug,以下是具体问题和修复方案:

核心问题

  • 类型错误:你定义的char *arr是单个字符的指针,但要存储字符串数组(二维字符数组),必须用char **arr(指向指针的指针)。当前代码中arr[counter_str - 1] = malloc(...)是把指针赋值给char类型变量,会截断地址,直接导致内存访问错误。
  • 变量类型错误:getchar()返回int类型(需容纳EOF这个特殊值),你把sym定义为char,如果系统中char是无符号类型,sym永远不会等于EOF,循环会无限执行。
  • 缓冲区溢出:string[50]的大小是固定的,但你没有检查counter是否超过数组上限(最多49,因为要留位置给终止符),一旦输入的单行内容过长,会越界写入,引发未定义行为。
  • 未处理EOF结尾的行:如果输入不是以换行符结束(比如直接按Ctrl+D/Ctrl+Z触发EOF),最后一行的内容根本不会被存入数组,因为只有遇到\n才会执行存储逻辑。
  • realloc风险:直接把realloc的结果赋值给arr,如果内存分配失败返回NULL,会丢失原来的内存地址,造成内存泄漏。
  • 内存泄漏:程序结束前没有释放arr和每个字符串占用的内存,虽然程序退出后系统会回收,但这是不良编程习惯。
  • 逻辑判断错误:原代码第一个if的括号位置有误,(sym != ' ') && (sym != (' ') && (sym != '\n'))的逻辑会变成先判断sym != '\t' && sym != '\n',再和sym != ' '做与运算,写法冗余且易混淆,应简化为sym != ' ' && sym != '\t' && sym != '\n'。

修复后的代码示例

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

#define MAX_LINE_LEN 50

int main()
{
    char **arr = NULL; // 改为指向指针的指针
    char string[MAX_LINE_LEN];
    int sym; // 改为int类型以容纳EOF
    int counter = 0;
    int counter_str = 0;

    while((sym = getchar()) != EOF)
    {
        // 检查缓冲区是否已满,留出位置给终止符
        if (counter >= MAX_LINE_LEN - 1) {
            fprintf(stderr, "行内容过长,截断处理\n");
            // 跳过当前行剩余字符
            while ((sym = getchar()) != EOF && sym != '\n');
            counter = 0;
            continue;
        }

        if(sym != ' ' && sym != '\t' && sym != '\n'){
            string[counter] = sym;
            counter++;
        }
        
        // 处理换行或EOF结尾的非空行
        if((sym == '\n') || (sym == EOF && counter > 0)){
            string[counter] = '\0'; // 若要保留换行符,可改为string[counter++] = '\n'; string[counter] = '\0';
            
            // 先将realloc结果存入临时变量,避免内存丢失
            char **temp = realloc(arr, (counter_str + 1) * sizeof(char*));
            if (!temp) {
                fprintf(stderr, "内存分配失败\n");
                // 释放已分配的内存
                for (int i = 0; i < counter_str; i++) {
                    free(arr[i]);
                }
                free(arr);
                return 1;
            }
            arr = temp;

            // 为当前行分配内存
            arr[counter_str] = malloc(strlen(string) + 1);
            if (!arr[counter_str]) {
                fprintf(stderr, "内存分配失败\n");
                // 释放已分配内存
                for (int i = 0; i < counter_str; i++) {
                    free(arr[i]);
                }
                free(arr);
                return 1;
            }
            strcpy(arr[counter_str], string);
            
            counter_str++;
            counter = 0;
        }
    }

    // 测试输出存储的内容
    printf("存储的%d行内容:\n", counter_str);
    for (int i = 0; i < counter_str; i++) {
        printf("%s\n", arr[i]);
        free(arr[i]); // 释放每个字符串的内存
    }
    free(arr); // 释放指针数组的内存

    return 0;
}

额外说明

  • 修复后的代码加入了内存分配失败的错误处理,避免程序崩溃或内存泄漏。
  • 如果需要保留每行的换行符,可调整终止符的赋值逻辑,把换行符加入string后再添加'\0'。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 07:15:31