C语言动态字符串数组创建问题:程序崩溃求排查
代码崩溃原因及修复方案
核心崩溃原因:未初始化二级指针pin
你声明了char **pin;但未给它分配内存空间,此时它是一个野指针,指向内存中的随机地址。执行pin[index] = malloc(...)时,本质是往随机内存位置写入数据,直接触发非法内存访问,导致程序崩溃。
其他严重问题
gets函数不安全:gets不检查输入长度,当输入字符串超过temp的80字节容量时,会造成缓冲区溢出,同样可能引发崩溃或未定义行为,C标准已废弃该函数,建议用fgets替代。- 内存泄漏:使用
malloc分配的内存未用free释放,长期运行会持续消耗系统内存。
修复后的代码示例
#include <stdio.h> #include <stdlib.h> #include <string.h> #define LINE 80 #define INIT_CAPACITY 4 // 初始分配的数组容量 int main(){ char **pin = NULL; char temp[LINE]; int index = 0; int capacity = INIT_CAPACITY; // 为二级指针分配初始内存 pin = (char**)malloc(capacity * sizeof(char*)); if(pin == NULL){ perror("malloc failed"); return 1; } puts("Gimme Books' Titles:"); // 用fgets替代gets,同时处理换行符 while(fgets(temp, LINE, stdin) != NULL){ // 移除fgets读取到的换行符 temp[strcspn(temp, "\n")] = '\0'; // 首字符为\x0时退出循环 if(temp[0] == '\x0'){ break; } // 存储数量超过当前容量时,动态扩容 if(index >= capacity){ capacity *= 2; char **temp_pin = (char**)realloc(pin, capacity * sizeof(char*)); if(temp_pin == NULL){ perror("realloc failed"); // 清理已分配内存,避免泄漏 for(int i=0; i<index; i++){ free(pin[i]); } free(pin); return 1; } pin = temp_pin; } // 为单个字符串分配内存并拷贝 pin[index] = (char*)malloc(strlen(temp)+1); if(pin[index] == NULL){ perror("malloc failed"); // 清理已分配内存 for(int i=0; i<index; i++){ free(pin[i]); } free(pin); return 1; } strcpy(pin[index], temp); index++; } puts("\nBooks' List:"); for(int k = 0; k < index; k++){ puts(pin[k]); } // 释放所有分配的内存 for(int k=0; k<index; k++){ free(pin[k]); } free(pin); return 0; }
修复要点说明
- 初始化并动态扩容
pin:先给pin分配初始容量,当存储的字符串数量超过当前容量时,用realloc扩容,避免内存不足。 - 替换
gets为fgets:fgets会限制读取字节数,避免缓冲区溢出,同时处理换行符保证字符串格式正确。 - 错误检查:每次
malloc和realloc后检查分配结果,避免空指针访问;分配失败时清理已分配内存,防止泄漏。 - 内存释放:程序结束前释放所有
malloc分配的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者stratakos
相关产品推荐
相关产品推荐

