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

C语言创建字符数组的数组:存储时程序崩溃,求代码修正方案

兄弟,我太懂这种程序突然崩溃的糟心感了!你说的这种「字符数组的数组」(本质是二维字符数组或者指针数组),最容易踩的坑就是内存管理或者赋值逻辑不对,我给你拆解下常见问题和修复方案:

先说说你大概率踩的坑

最常见的崩溃原因就是错误地让指针指向了栈上的临时内存,或者没给子数组分配内存就直接写入:
比如你可能写过类似这样的错误代码:

void wrong_code() {
    char* sentences[3]; // 指针数组,存每个句子的地址
    char temp[100];     // 栈上的临时数组
    for(int i=0; i<3; i++){
        fgets(temp, 100, stdin);
        sentences[i] = temp; // 所有指针都指向同一个temp!
    }
    // 这里访问sentences[0]就可能崩溃,因为temp是栈内存,函数结束后会被释放
}

或者是动态分配时漏给子数组分配内存:

char** sentences = malloc(3 * sizeof(char*));
for(int i=0; i<3; i++){
    fgets(sentences[i], 100, stdin); // sentences[i]是空指针,直接写入会踩内存崩溃
}
两种靠谱的实现方案

根据你的需求场景,我给你两种可行的写法:

方案一:固定大小的二维字符数组(简单易上手)

如果你能预估句子的最大长度和最多句子数量,用这种固定大小的数组最省心,不需要手动管理内存:

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

#define MAX_SENTENCES 5  // 最多存5个句子
#define MAX_SENTENCE_LEN 100 // 每个句子最长100字符

int main() {
    char sentences[MAX_SENTENCES][MAX_SENTENCE_LEN];
    int sentence_count = 0;

    printf("输入最多5个句子(输入空行结束):\n");
    while(sentence_count < MAX_SENTENCES) {
        // 读取句子
        if(fgets(sentences[sentence_count], MAX_SENTENCE_LEN, stdin) == NULL) {
            break;
        }
        // 去掉fgets自带的换行符
        sentences[sentence_count][strcspn(sentences[sentence_count], "\n")] = '\0';
        // 输入空行就停止
        if(strlen(sentences[sentence_count]) == 0) {
            break;
        }
        sentence_count++;
    }

    // 验证存储结果
    printf("\n你输入的句子是:\n");
    for(int i=0; i<sentence_count; i++) {
        printf("%d: %s\n", i+1, sentences[i]);
    }
    return 0;
}

方案二:动态分配的指针数组(灵活适配不确定长度)

如果句子长度或数量不确定,用动态分配的指针数组更灵活,每个句子单独分配内存:

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

#define INITIAL_CAPACITY 2  // 初始最多存2个句子
#define BUFFER_SIZE 100     // 临时缓冲区大小

int main() {
    // 先分配指针数组的内存
    char** sentences = malloc(INITIAL_CAPACITY * sizeof(char*));
    if(sentences == NULL) {
        perror("内存分配失败");
        return 1;
    }
    int capacity = INITIAL_CAPACITY;
    int sentence_count = 0;
    char buffer[BUFFER_SIZE];

    printf("输入句子(输入空行结束):\n");
    while(1) {
        if(fgets(buffer, BUFFER_SIZE, stdin) == NULL) {
            break;
        }
        // 去掉换行符
        buffer[strcspn(buffer, "\n")] = '\0';
        if(strlen(buffer) == 0) {
            break;
        }

        // 如果当前容量不够,扩容指针数组
        if(sentence_count >= capacity) {
            capacity *= 2;
            char** temp = realloc(sentences, capacity * sizeof(char*));
            if(temp == NULL) {
                perror("扩容失败");
                // 记得释放已经分配的内存,避免泄漏
                for(int i=0; i<sentence_count; i++) {
                    free(sentences[i]);
                }
                free(sentences);
                return 1;
            }
            sentences = temp;
        }

        // 为当前句子分配内存(要包含字符串终止符)
        sentences[sentence_count] = malloc(strlen(buffer) + 1);
        if(sentences[sentence_count] == NULL) {
            perror("句子内存分配失败");
            // 清理已分配的内存
            for(int i=0; i<sentence_count; i++) {
                free(sentences[i]);
            }
            free(sentences);
            return 1;
        }
        // 把缓冲区的内容复制到分配的内存里
        strcpy(sentences[sentence_count], buffer);
        sentence_count++;
    }

    // 验证存储结果
    printf("\n你输入的句子是:\n");
    for(int i=0; i<sentence_count; i++) {
        printf("%d: %s\n", i+1, sentences[i]);
    }

    // 记得释放所有动态分配的内存
    for(int i=0; i<sentence_count; i++) {
        free(sentences[i]);
    }
    free(sentences);
    return 0;
}
关键注意点总结
  • 如果用指针数组,绝对不能直接把栈上的临时字符数组赋值给指针,必须用malloc分配内存后再用strcpy复制内容。
  • 动态分配内存后一定要检查是否分配成功,避免空指针访问导致崩溃。
  • 用完动态分配的内存要记得释放,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:23:18