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
相关产品推荐
相关产品推荐

