【问题标题】:How can realloc not work but malloc can?realloc 怎么不能工作,而 malloc 可以?
【发布时间】:2011-08-22 12:31:18
【问题描述】:

我已经到了 realloc 停止返回指针的地步——我假设数组没有空间来扩展或移动。唯一的问题是我真的需要该内存存在或应用程序无法按预期运行,所以我决定尝试 malloc - 期待它不起作用,因为 realloc 不起作用 - 但它确实如此。为什么?

然后我将指针数组memcpy到新分配的数组中,但发现它破坏了它,像0x10和0x2b这样的指针被放入了数组中。有真正的指针,但如果我用 for 循环替换 memcpy,就可以修复它。为什么 memcpy 这样做?我不应该在我的代码中使用 memcpy 吗?

代码:

float * resizeArray_by(float *array, uint size)
{
    float *tmpArray = NULL;
    if (!array)
    {
        tmpArray = (float *)malloc(size);
    }
    else
    {
        tmpArray = (float *)realloc((void *)array, size);
    }

    if (!tmpArray)
    {
        tmpArray = (float *)malloc(size);
        if (tmpArray)
        {
            //memcpy(tmpArray, array, size - 1);
            for (int k = 0; k < size - 1; k++)
            {
                ((float**)tmpArray)[k] = ((float **)array)[k];
            }
            free(array);
        }
    }

    return tmpArray;
}

void incrementArray_andPosition(float **& array, uint &total, uint &position)
{
    uint prevTotal = total;
    float *tmpArray = NULL;
    position++;
    if (position >= total)
    {
        total = position;
        float *tmpArray = resizeArray_by((float *)array, total);
        if (tmpArray)
        {
            array = (float **)tmpArray;

            array[position - 1] = NULL;
        }
        else
        {
            position--;
            total = prevTotal;
        }
    }
}

void addArray_toArray_atPosition(float *add, uint size, float **& array, uint &total, uint &position)
{
    uint prevPosition = position;
    incrementArray_andPosition(array, total, position);

    if (position != prevPosition)
    {
        float *tmpArray = NULL;
        if (!array[position - 1] || mHasLengthChanged)
        {
            tmpArray = resizeArray_by(array[position - 1], size);
        }

        if (tmpArray)
        {
            memcpy(tmpArray, add, size);
            array[position - 1] = tmpArray;
        }
    }
}

经过我的所有修复后,代码可能会初始化。这里有趣的是,在对数组进行排序之后,我用 malloc 分配了一个巨大的数组,因此将这些数组重新排序为一个数组以用作 GL_ARRAY_BUFFER。如果 realloc 因为空间不足而没有分配,那为什么不分配呢?

最后,这导致它最终崩溃。在通过渲染功能后一旦它崩溃。如果我删除了所有修复程序并在 realloc 未分配时被捕获,它会正常工作。这引出了一个问题,分配我的数组而不是重新分配会导致进一步的问题有什么问题?

我的数组是浮点指针的指针。当我增大数组时,它会转换为指向浮点数的指针并重新分配。我在 Android 上构建,所以这就是我认为内存不足的原因。

【问题讨论】:

  • 不看代码很难理解问题是什么。您能否提供一些有关您使用 memcpy 的背景信息?实际的 realloc 和 malloc 调用?
  • 听起来这里有一个错误。无论是在您的代码中,还是在 CRT 中(不太可能)。
  • 你混淆了'size'变量的含义吗?是数组的大小(以字节为单位)还是数组中的浮点数?
  • 为什么你的问题同时被标记为 C 和 C++?
  • @AndreyT 因为我正在用 C++ 编写 C,因为 android-ndk

标签: c++ c malloc android-ndk realloc


【解决方案1】:

顺便说一句,您不需要测试array 是否为NULL

你可以替换

if (!array)
{
    tmpArray = (float *)malloc(size);
}
else
{
    tmpArray = (float *)realloc((void *)array, size);
}

通过

tmpArray = realloc(array, size*sizeof (float));

realloc 在给定 NULLpointer 时的行为类似于 malloc

另外一件事,注意size不是0,因为realloc with 0 as size是一样的 free.

第三点,在非绝对必要时不要类型转换指针。您对分配函数的返回进行了类型转换,自 ANSI-C 以来,这被认为是不好的做法。它在 C++ 中是强制性的,但是当您使用 C 分配时,您显然不在 C++ 中(在这种情况下,您应该使用 new/delete)。 将数组变量强制转换为 (void *) 也是不必要的,因为如果您的参数被错误声明(它可能是 int 或指向指针的指针,并且通过强制转换您会抑制警告),它可能会隐藏一些警告。

【讨论】:

    【解决方案2】:

    您混淆了size 和指针类型。在内存分配中,size 是字节数,您将指针类型转换为float *,实质上创建了一个大小为size / sizeof(float)float 数组。在 memcpy 等效代码中,您将数组视为 float ** 并复制其中的 size。假设sizeof(float *) &gt; 1,这将破坏堆,并且很可能是以后问题的根源。

    此外,如果您将 100 大小的数组复制到 200 大小的数组,则需要复制超过 100 个元素,而不是 200 个。复制超出数组的末尾(这就是您正在做的) 可能导致程序崩溃。

    一个动态分配的指向floats 的指针数组将是float ** 类型,而不是float *,当然也不是两者的混合。数组的大小是分配给malloc和friends的字节数,以及所有数组操作中的元素个数。

    memcpy 将忠实地复制字节,假设源和目标块不重叠(并且单独分配的内存块不重叠)。但是,您已经为复制的字节数指定了size - 1,而复制的数字应该是旧数组的确切字节大小。 (无论如何,你在哪里得到错误的指针值?如果它在数组的扩展部分中,那么你无论如何都会在其中复制垃圾。)如果memcpy 给你废话,那么一开始就是废话,它不是'你的问题。

    【讨论】:

    • 当我打印 memcpy 数组 memcpy(tmpArray, array, size - 1) 的值时,我得到了错误的指针。
    【解决方案3】:

    从所有不同的信息位(realloc 找不到内存,memcpy 行为异常,崩溃)来看,这听起来很像堆损坏。如果没有一些代码示例来说明您正在做什么,很难确定,但您似乎在某些时候对内存管理不当,导致堆进入无效状态。

    您是否能够在 Linux 等替代平台上编译您的代码(您可能需要存根一些 android 特定的 API)?如果是这样,您可以查看该平台上发生的情况和/或使用 valgrind 来帮助追捕它。

    最后,既然你有这个标记 C++,你为什么要使用 malloc/realloc 而不是 vector(或其他标准容器)或 new

    【讨论】:

    • 在 android-ndk 上,标准库不存在。我最初确实使用了矢量。由于 C++ 中没有 realloc,所以我用 C 编写。
    猜你喜欢
    • 2013-11-22
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多