2011-05-10 53 views
1

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

然后我将指针数组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; 
     } 
    } 
} 

我所有修补程序后,代码可能inits。这里有趣的是,在对数组进行分类之后,我用malloc分配了一个巨大的数组,因此将这些数组重新排列成一个数组,以用作GL_ARRAY_BUFFER。如果realloc由于缺少空间而没有分配,那么为什么不分配?

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

我的数组的指针是浮点指针。当我增长数组时,它被转换为一个指向浮点数并重新分配的指针。我在Android上构建,所以这就是为什么我认为那里缺乏内存。

+0

在看不到代码的情况下很难理解问题所在。你能否包含一些关于你使用memcpy的内容?实际的realloc和malloc调用? – 2011-05-10 14:32:02

+0

听起来像这里工作的错误。无论是在你的代码中,还是在CRT中(不太可能)。 – 2011-05-10 14:36:11

+0

你在混合'size'变量的含义吗?它是以字节为单位的数组大小还是数组中的浮点数? – James 2011-05-10 15:20:25

回答

1

你很困惑size和指针类型。在内存分配中,size是字节数,并且您正在将指针类型转换为float *,实际上会创建大小为size/sizeof(float)float的数组。在memcpy相当的代码中,您将数组视为float **并将它们复制size。这会破坏堆,假设sizeof(float *) > 1,并且可能是后来问题的来源。此外,如果您要将100个大小的数组复制到200个大小的数组中,则需要复制100个以上的元素,而不是200个。 )会导致程序崩溃。

指向float的指针的动态分配数组将是float **类型,而不是float *,当然不是这两者的混合。数组的大小是指向malloc和朋友的字节数,以及所有数组操作中的元素数。假设源块和目标块不重叠(并且分别分配的存储块不包含),则将忠实地复制字节。但是,当复制的数字应该是旧数组的确切字节大小时,您已指定size - 1复制的字节数。 (无论如何,你会得到错误的指针值?如果它在数组的扩展部分,那么你就是在那里复制垃圾。)如果memcpy给你胡说八道,这开始变得无稽之谈了,而不是你的问题。

+0

当我输出memcpy数组memcpy(tmpArray,array,size - 1)的值时,我得到了坏指针。 – NebulaFox 2011-05-10 17:11:02

3

从所有不同位的信息来看(realloc找不到内存,memcpy意外行为,崩溃),这听起来很像堆损坏。如果没有一些你正在做的事情的代码示例,很难说清楚,但是看起来你在某些时候错误地管理了内存,导致堆进入无效状态。

您是否能够在Linux等其他平台上编译代码(您可能需要存储一些特定于android的API)?如果是这样,你可以看到该平台上发生了什么和/或使用valgrind来帮助追捕它。

最后,你有这个标记的C++为什么你使用malloc/realloc而不是,例如,vector(或另一个标准容器)或new

+2

+1为“你为什么用C++编程C?” – 2011-05-10 14:52:44

+0

在android-ndk上,标准库不存在。我原本使用矢量。因为在C++中没有realloc,所以我使用C编写。 – NebulaFox 2011-05-10 14:54:43

0

而且顺便说一句,你不需要测试,如果arrayNULL

可以给出一个NULL指针,当像malloc通过

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

realloc行为取代

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

另一件事,小心大小不是0,因为realloc与0大小是一样的 free

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

相关问题