【问题标题】:Problems with simple dynamic memory allocation简单动态内存分配的问题
【发布时间】:2021-05-07 11:42:35
【问题描述】:

最近学习了 C 中的动态内存分配,并试图编写一个简单的程序来读取一堆单词,将它们存储在动态数组中,然后以相反的顺序打印单词,但我在执行时遇到了分段错误。请不要对我太苛刻,我只是在学习,任何帮助将不胜感激!

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

int main()
{
    char **arr = (char **)malloc(1 * sizeof(char *));
    int maxarr = 1, arrsz = 0;
    for (;;)
    {
        if (arrsz >= maxarr)
        {
            maxarr *= 2;
            arr = (char **)realloc(arr, maxarr * sizeof(char *));
            if (!arr)
                return -1;
        }
        arr[arrsz] = (char *)malloc(1 * sizeof(char));
        int i = arrsz++;
        int sz = 0, mx = 1;
        char ch = getchar();
        while (ch != ' ' && ch != '\n')
        {
            if (sz >= mx)
            {
                mx *= 2;
                arr[i] = (char *)realloc(arr[i], mx * sizeof(char));
                if (!arr[i])
                    return -1;
            }
            arr[i][sz++] = ch;
            ch = getchar();
        }
        if (sz >= mx)
        {
            mx++;
            arr[i] = (char *)realloc(arr[i], mx * sizeof(char));
            if (!arr[i])
                return -1;
        }
        arr[i][sz++] = '\0';
        if (ch == '\n')
            break;
    }

    for (int i = arrsz - 1; i >= 0; i--)
    {
        if (arr[i] != NULL)
            printf("%s ", arr[i]);
    }

    for (int i = 0; i < maxarr; i++)
        free(arr[i]);
    free(arr);
    printf("\n");
}

【问题讨论】:

  • 你有一个无限循环。做int c; while( ( c = getchar()) != EOF)getchar 返回一个整数。
  • @WilliamPursell 这不是无限的。当遇到 \n 时它会中断。
  • @LukaSsS 如果用户在输入空格或换行符之前按下文件结束键会发生什么?还是使用输入重定向?还是管道?
  • @Someprogrammerdude 哦,现在我知道这可能是个问题了,谢谢,虽然这只是一个练习,以了解所有 alloc-s 的工作原理。

标签: c memory-management dynamic-memory-allocation


【解决方案1】:
    for (int i = 0; i < maxarr; i++)
        free(arr[i]);

这很糟糕,因为从 arr[arrsz]arr[maxarr-1] 的元素未初始化。使用通过malloc() 分配且未初始化的缓冲区值会调用未定义的行为

应该是:

    for (int i = 0; i < arrsz; i++)
        free(arr[i]);

【讨论】:

    【解决方案2】:

    我的两分钱:

    您应该始终检查您的malloc 呼叫是否成功。不仅适用于realloc 电话。

    之后:

    char **arr = (char **)malloc(1 * sizeof(char *));

    你应该添加:

    if (!arr) return -1;

    另外一点,对于您潜在的realloc 故障,请尽量让堆处于相对良好的状态。而不是直接返回,您应该尝试在之前清理arr,因为它是本地的并且仅在您的函数中使用。我建议你添加一个自定义的reallocfunction,它会在失败的情况下进行清理,然后你的 main 函数可以在失败的情况下直接返回 -1。

    【讨论】:

      猜你喜欢
      • 2011-01-19
      • 2022-01-22
      • 2011-02-17
      • 2022-12-05
      • 2011-03-24
      • 2012-05-02
      • 1970-01-01
      • 2011-09-13
      相关资源
      最近更新 更多