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

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;
}

修复要点说明

  1. 初始化并动态扩容pin:先给pin分配初始容量,当存储的字符串数量超过当前容量时,用realloc扩容,避免内存不足。
  2. 替换gets为fgets:fgets会限制读取字节数,避免缓冲区溢出,同时处理换行符保证字符串格式正确。
  3. 错误检查:每次malloc和realloc后检查分配结果,避免空指针访问;分配失败时清理已分配内存,防止泄漏。
  4. 内存释放:程序结束前释放所有malloc分配的内存,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:11:07