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

调用realloc扩容char**后程序崩溃,求排查与解决

问题分析与修复

核心错误点

  • 内存分配单位错误:malloc(size * sizeof(char))和realloc(words, size * sizeof(char))中,words是char**类型,每个元素是指针,应该用sizeof(char*)计算每个元素的内存大小。
  • 非法释放野指针:循环中i++后立即执行free(words[i]),此时words[i]未被分配内存,属于野指针,直接触发内存访问错误。
  • 字符串缺少终止符:strncpy仅复制指定长度的字符,不会自动添加'\0',若输入单词长度等于maxLength,复制后的字符串无终止符,会导致内存越界。
  • 输入缓冲区溢出:fscanf("%s", line)未限制读取长度,当输入单词超过maxLength时,会溢出line数组,破坏栈内存。

修复后的代码

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

#define S 8

char ** readLines(int * wordCountp, int maxLength) {
    char line[maxLength + 1];
    int size = S;
    // 修正:用sizeof(char*)分配指针数组内存
    char ** words = malloc(size * sizeof(char*));
    if (words == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(1);
    }
    
    int i = 0;
    // 修正:构造限制长度的格式字符串,避免line缓冲区溢出
    char fmt[32];
    snprintf(fmt, sizeof(fmt), "%%%ds", maxLength);
    
    while (fscanf(stdin, fmt, line) == 1) {
        words[i] = malloc((maxLength + 1) * sizeof(char));
        if (words[i] == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            exit(1);
        }
        // 修正:复制后手动添加终止符
        strncpy(words[i], line, maxLength);
        words[i][maxLength] = '\0';
        
        i++;
        if (i == size) {
            size *= 2;
            // 修正:用sizeof(char*)扩容指针数组,并用临时变量接收结果避免内存丢失
            char ** temp = realloc(words, size * sizeof(char*));
            if (temp == NULL) {
                fprintf(stderr, "Memory allocation failed\n");
                exit(1);
            }
            words = temp;
        }
    }
    // 确保指针数组末尾为NULL,作为结束标记
    if (i < size) {
        words[i] = NULL;
    }
    *wordCountp = i;
    return words;
}

关键修改说明

  1. 内存分配修正:将sizeof(char)替换为sizeof(char*),确保指针数组的每个元素都能容纳一个char*指针。
  2. 移除非法free:删除循环中的free(words[i]),保留读取到的字符串内存。
  3. 添加字符串终止符:复制完成后手动设置words[i][maxLength] = '\0',保证字符串正确终止。
  4. 限制输入长度:通过snprintf构造格式字符串"%Ns"(N为maxLength),让fscanf最多读取maxLength个字符,避免line数组溢出。
  5. 安全扩容:用临时变量temp接收realloc的返回值,避免realloc失败时丢失原指针指向的内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 03:35:24