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

C语言内存分配与输入处理问题求助

解决动态字符串数组的段错误问题

你遇到的两个段错误,核心原因都是指针传递方式错误,再加上一点细节逻辑问题:

问题根源拆解

  1. 指针按值传递,主函数拿不到修改后的数组
    leArgs函数里的char **arg是按值传进来的,你在函数里用realloc修改arg的指向,只会改这个局部变量,主函数里的str还是一开始的NULL。所以不管你在leArgs里存了多少内容,主函数访问str[0]都是在操作空指针,直接触发段错误。

  2. 索引逻辑的小瑕疵
    虽然第一次循环时args和数组长度的对应没问题,但num_args先自增再分配内存,用num_args-1作为索引比依赖args变量更稳妥,能避免循环次数多了可能出现的索引越界。

修复后的完整代码

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

#define INVERSO "inverso"
#define LEN_INVERSO 8

#define TRUE 1
#define FALSE 0

#define FIM_LINHA -1
#define NOTVALID -1

#define BUFFER 65535 

enum arg {PRIMEIRO, SEGUNDO, TERCEIRO, QUARTO, QUINTO};

int is_space ( int c ) {
    return (c == '\t' || c == ' ' || c == '\n'); 
}

int NotEndOfLine ( char character ) {
    return character != '\n';
}

int leNome ( char *buff ) {
    int character, aspas = FALSE, i = 0;

    // 跳过前导空白,处理直接输入换行的情况
    while ( is_space (character = getchar()) ) {
        if ( !NotEndOfLine(character) ) {
            buff[0] = '\0';
            return FIM_LINHA;
        }
    }

    do {
        if (character == '\"')
            aspas = (aspas == FALSE) ? TRUE : FALSE;
        else
            buff[i++] = character;

    } while ( !is_space(character = getchar() ) || aspas == TRUE );

    buff[i] = '\0';  // 修正:i已经指向字符串末尾,无需再i++
    return !NotEndOfLine ( character );
}

// 改成指向指针的指针,让函数能修改主函数里的str指针
int leArgs ( char ***arg ) {
    int num_args = 0, args = PRIMEIRO, lenght, endline;
    char buff[BUFFER];

    do {
        endline = leNome( buff );
        printf("Run: %d\n" , args);
        if ( endline == FIM_LINHA )
            return num_args;

        // 操作主函数传来的指针地址,更新数组
        *arg = realloc(*arg, sizeof(char*) * (++num_args));
        if (*arg == NULL) {
            perror("realloc失败");
            exit(EXIT_FAILURE);
        }

        lenght = strlen(buff);
        // 用num_args-1做索引,避免args变量的干扰
        (*arg)[num_args - 1] = malloc(sizeof(char) * (lenght + 1));
        if ((*arg)[num_args -1] == NULL) {
            perror("malloc失败");
            exit(EXIT_FAILURE);
        }
        strcpy((*arg)[num_args - 1], buff);
        
        printf("buff:%s num_args:%d\n", buff, num_args);
        printf("Argumento: %s\n", (*arg)[num_args - 1]);
        putchar('\n');
        args++;

    } while ( endline == FALSE );

    return num_args;
}

int main(){
    int i, num_args;
    char **str = NULL;
    // 传递str的地址给leArgs
    num_args = leArgs(&str);

    if (num_args > 0) {
        printf("%s ", str[0]);
        puts("sucesso ");

        for(i = 0; i < num_args; i++){
            printf("i:%d ", i);
            printf("%d:%s\n", i, str[i]);
        }

        // 释放动态分配的内存,避免泄漏
        for(i = 0; i < num_args; i++){
            free(str[i]);
        }
        free(str);
    } else {
        puts("没有输入任何有效参数");
    }

    return 0;
}

关键修复点说明

  • 指针传递方式修改:把leArgs的参数改成char ***arg,主函数传递&str,这样函数内部对*arg的修改会直接同步到主函数的str指针,解决了主函数拿不到数组的问题。
  • 字符串终止符修正:leNome里原代码的buff[i++] = '\0'会导致字符串末尾多占一个无用字节,改成buff[i] = '\0'更准确。
  • 添加内存分配失败检查:realloc和malloc可能返回空指针,加个判断能提前发现错误,避免后续崩溃。
  • 空输入判断:主函数里先检查num_args是否大于0,避免用户没输入内容时访问空指针。
  • 内存释放:动态分配的内存一定要记得释放,防止内存泄漏。
  • 索引逻辑简化:用num_args-1作为数组索引,不再依赖args变量,代码逻辑更清晰,减少出错可能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 01:22:03