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

C语言realloc内存重分配异常致程序终止问题求助

解决realloc导致程序终止的问题

核心错误分析

  • 输入处理与内存越界

    1. 输入size后,scanf会在缓冲区留下换行符,后续fgets会优先读取这个空行,导致输入验证逻辑混乱。你用while(fgets(...))循环读取到EOF的逻辑,会让buffer仅保留最后一次读取内容,且输入的数字串没有终止符,strcpy(list, buffer)会因找不到'\0'越界,破坏堆内存结构,为后续realloc崩溃埋下隐患。
    2. 初始malloc仅分配size*sizeof(char)内存,但strcpy需要目标内存容纳字符串终止符,应分配size+1字节。
  • realloc内存计算错误
    size++后,新内存大小应为(size+1)*sizeof(char)(预留终止符空间),原代码写成size+1,结合之前的堆破坏问题,直接触发程序终止。

  • 元素存储类型不匹配
    原有列表存储数字字符(如'1'对应ASCII 49),但添加元素时直接将int类型的tempElem(如输入3得到值3)存入数组,实际存储的是ASCII值3(不可见字符),导致排序和打印逻辑完全错误,应转换为对应字符:list[size-1] = tempElem + '0';

  • 循环退出条件错误
    主循环while(input != 0)不符合需求,应改为while(input != 2),否则输入2无法退出程序。

修正后的代码

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

void insert(int size, char *arr);
void swap(char *arr, int pos1, int pos2);
void printList(int size, char *arr);

int main()
{
    int size = 0;
    do
    {
        printf("Put in size of the list (Range[1;2^16-1]): ");
        scanf(" %d", &size);
        if (size <= 0)
            printf("Put in a correct length!\n");
    } while (size <= 0);

    // 清除scanf遗留的换行符
    getchar();

    printf("Put in ur List: ");
    char buffer[size + 2]; // 预留换行符和终止符空间
    int errFlag;
    do
    {
        errFlag = 1;
        // 仅读取一行输入
        if (!fgets(buffer, sizeof(buffer), stdin))
        {
            errFlag = 0;
            break;
        }
        // 去掉换行符并添加终止符
        buffer[strcspn(buffer, "\n")] = '\0';
        // 验证输入长度是否符合要求
        if (strlen(buffer) != size)
            errFlag = 0;
        // 验证输入是否全为数字
        for (int i = 0; i < size; i++)
            if (!isdigit(buffer[i]))
                errFlag = 0;
        if (errFlag == 0)
            printf("Input failed try again: ");
    } while (errFlag == 0);

    // 分配包含终止符的内存
    char *list = malloc((size + 1) * sizeof(char));
    if (!list)
    {
        perror("malloc failed");
        return 1;
    }
    strcpy(list, buffer);
    insert(size, list);
    printList(size, list);

    int input = 0;
    do
    {
        printf("\nDo u want to add another element(1) or a list(0)? If u want to stop type (2): ");
        scanf(" %d", &input);
        if (input != 0 && input != 1 && input != 2)
            printf("\nInput failed try again: ");
        else if (input == 1)
        {
            int tempElem = 0;
            printf("Input ur element: ");
            scanf(" %d", &tempElem);
            // 验证输入为单个数字
            if (tempElem < 0 || tempElem > 9)
            {
                printf("Please input a single digit!\n");
                continue;
            }
            size++;
            // 用临时指针接收realloc结果,避免内存泄漏
            char *temp_list = realloc(list, (size + 1) * sizeof(char));
            if (!temp_list)
            {
                perror("realloc failed");
                free(list);
                return 1;
            }
            list = temp_list;
            // 将int转为对应字符存储
            list[size - 1] = tempElem + '0';
            list[size] = '\0'; // 确保字符串终止符
            printf("New ");
            insert(size, list);
            printList(size, list);
        }
    } while (input != 2); // 输入2退出程序

    free(list); // 释放动态内存
    return 0;
}

void insert(int size, char *arr)
{
    for (int i = 1; i < size; i++)
    {
        int j = i - 1;
        while (j >= 0 && arr[j] > arr[j + 1])
        {
            swap(arr, j, j + 1);
            j--;
        }
    }
}

void swap(char *arr, int pos1, int pos2)
{
    char temp = arr[pos1];
    arr[pos1] = arr[pos2];
    arr[pos2] = temp;
}

void printList(int size, char *arr)
{
    printf("ArrayList: ");
    for (int i = 0; i < size; i++)
    {
        printf("[%d] ", arr[i] - '0');
    }
}

修正说明

  1. 处理scanf遗留的换行符,避免fgets读取空行。
  2. 优化输入读取逻辑,只读取一行并验证长度和字符合法性。
  3. 内存分配时预留字符串终止符空间,彻底解决越界问题。
  4. 用临时指针接收realloc结果,避免分配失败时丢失原内存地址。
  5. 统一存储格式,将新增数字转为对应字符。
  6. 修正循环退出条件,符合需求逻辑。
  7. 程序结束前释放动态内存,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 11:01:25