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

C语言动态内存存储字符串时的重复输入与Heap Buffer Overflow问题

C程序动态内存分配问题修复

问题1:重复提示输入的修复

原代码中,fgets成功读取输入后,else分支又额外调用了一次fgets,导致每次输入被读取两次,进而出现两次提示。直接删除else块内的fgets调用即可,保留if分支的读取逻辑。

问题2:堆缓冲区溢出的修复

堆溢出的核心原因是分配内存时未给字符串终止符\0预留空间:

  • strlen(line)返回的是字符串中有效字符的长度(不包含末尾的\0),malloc(sizeof(char) * strlen(line))只分配了存储有效字符的空间,没有给\0留位置。后续printf打印字符串时会越界读取内存,触发缓冲区溢出。
  • 修复方式:分配内存时多申请1字节空间用于存储\0,即改为malloc(strlen(line) + 1);复制字符串时,使用strcpy自动完成\0的复制,或者用memcpy后手动添加\0。

另外补充潜在问题处理:realloc和malloc可能返回NULL,实际开发中需要检查返回值,避免内存泄漏或崩溃。

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER 255

int main(void) 
{
    char line[BUFFER];
    int item = 0;
    // 初始分配1个指针的空间
    char** data = malloc(sizeof(char*));
    if (data == NULL) {
        perror("malloc failed");
        return 1;
    }
    
    for(;;)
    {
        printf("Enter string %d: ", item + 1);

        if (fgets(line, BUFFER, stdin) == NULL)
        {
            break;
        }

        // 重新分配内存,预留当前总需要的指针数
        char** temp = realloc(data, sizeof(char*) * (item + 1));
        if (temp == NULL) {
            perror("realloc failed");
            // 清理已分配内存避免泄漏
            for (int i = 0; i < item; i++) {
                free(data[i]);
            }
            free(data);
            return 1;
        }
        data = temp;

        // 分配内存时+1,为'\0'预留空间
        data[item] = malloc(strlen(line) + 1);
        if (data[item] == NULL) {
            perror("malloc failed for string");
            // 清理已分配资源
            for (int i = 0; i < item; i++) {
                free(data[i]);
            }
            free(data);
            return 1;
        }
        // 使用strcpy自动复制'\0'
        strcpy(data[item], line);

        item++;
    }
    
    printf("\n\nElements:\n");
    
    for(int j = 0; j < item; j++)
    {
        printf("%s", data[j]);
        free(data[j]);
    }

    free(data);

    return 0;
}

关键修改点说明

  1. 删除else块内重复的fgets调用,解决重复提示问题。
  2. 内存分配时改为strlen(line) + 1,为字符串终止符预留空间。
  3. 使用strcpy替代memcpy,自动处理字符串终止符(也可保留memcpy,但需手动添加data[item][strlen(line)] = '\0')。
  4. 增加内存分配失败的检查与资源清理逻辑,避免程序崩溃或内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 05:10:49