realloc()触发异常

时间:2014-06-17 16:20:47

标签: c memory heap-corruption

我正在编写一个接收数组(任何类型)的泛型函数,并在该数组中找到最大值(根据指定的compare()方法),然后返回一个指针数组,其中包含指向该数组的所有实例的指针指定数组中的值。

问题是,当我尝试重新分配以增加指针数组result的大小时,我看到我的程序触发了一个断点,如果我按下继续几次,就会发生这种情况:

Homework 5.3.exe has triggered a breakpoint.
HEAP[Homework 5.3.exe]: Heap block at 00806988 modified at 008069C0 past requested size of 2c
Homework 5.3.exe has triggered a breakpoint.
HEAP[Homework 5.3.exe]: Invalid address specified to RtlReAllocateHeap( 007F0000, 00806990 )
Homework 5.3.exe has triggered a breakpoint.
First-chance exception at 0x00F5464C in Homework 5.3.exe: 0xC0000005: Access violation writing location 0x00000020.
Unhandled exception at 0x00F5464C in Homework 5.3.exe: 0xC0000005: Access violation writing location 0x00000020.
The program '[7212] Homework 5.3.exe' has exited with code 0 (0x0).

这是我的代码:

void ** gMax(void * firstElement, void * lastElement, int sizeOfElement, int (*compare)(void * p1, void * p2))
{
    void ** result;
    int i, counter = 0;
    void * max = firstElement;
    if((result = (void **) malloc(sizeOfElement)) == NULL) return NULL;
    for(i = 0; i < ((char *)lastElement) - ((char *) firstElement); i += sizeOfElement)
    {
        printf("%d\n", *(int *)max);
        if(compare((char *)firstElement + i, max) > 0) max = (char *) firstElement + i;
    }
    for(i = 0; i < ((char *)lastElement) - ((char *) firstElement); i += sizeOfElement)
    {
        if(compare((char *)firstElement + i, max) == 0)
        {
            *(result + counter++ * sizeOfElement) = max;
            result = (void **) realloc(result, (counter + 1) * sizeOfElement);
        }
    }
    *(result + counter++ * sizeOfElement) = NULL;
    return result;
}
int main()
{
    int i;
    int a[] = { 2, 7, 5, 1, 7, 4, 7 };
    char b[][10] = { "xyz", "abc", "aaaa", "xyz" };
    int ** resultA = (int **) gMax(a, a + sizeof(a)/sizeof(*a), sizeof(*a), compareInt);
    char ** resultB = (char **) gMax(b, b + sizeof(b)/sizeof(*b), sizeof(*b), compareStringArray);
    return 0;
}

断点在result = (void **) realloc(result, (counter + 1) * sizeOfElement);

处触发

我做错了什么?

编辑: 由于Skizz的回答,我将我的代码更改为:

void ** gMax(void * firstElement, void * lastElement, int sizeOfElement, int (*compare)(void * p1, void * p2))
{
    void ** result;
    int i, counter = 0;
    void * max = firstElement;
    if((result = (void **) malloc(sizeof(void *))) == NULL) return NULL;
    for(i = 0; i < ((char *)lastElement) - ((char *) firstElement); i += sizeOfElement)
    {
        printf("%d\n", *(int *)max);
        if(compare((char *)firstElement + i, max) > 0) max = (char *) firstElement + i;
    }
    for(i = 0; i < ((char *)lastElement) - ((char *) firstElement); i += sizeOfElement)
    {
        if(compare((char *)firstElement + i, max) == 0)
        {
            *(result + counter++ * sizeof(void *)) = max;
            result = (void **) realloc(result, (counter + 1) * sizeof(void *));
        }
    }
    *(result + counter++ * sizeof(void *)) = NULL;
    return result;
}

但它仍然是同样的问题......

感谢。

2 个答案:

答案 0 :(得分:4)

你的'result'数组是一个指针数组,而不是一个项目数组(intchar等)。因此,您对此数组的索引是错误的: -

*(result + counter++ * sizeOfElement ) = max;

上面突出显示的项目不是必需的,指针算术已经考虑了元素的大小(在这种情况下是void *)。

你遇到的另一个问题是你的记忆分配: -

result = (void **) malloc(sizeOfElement)

realloc(result, (counter + 1) * sizeOfElement)

您没有分配element类型的数组,而是分配pointers to elementsvoid *)数组,因此不需要sizeOfElement,而应该是而是sizeof (void *)

答案 1 :(得分:1)

您的“已修改”版本仍然存在相同的错误。

您的代码是:

*(result + counter++ * sizeof(void *)) = max;
result = (void **) realloc(result, (counter + 1) * sizeof(void *));

此代码可以用without cruft表示并使用索引表示法:

result[counter * sizeof(void *)] = max;
++counter;
result = realloc(result, (counter + 1) * sizeof(void *));

索引错误。你应该这样做:

result[counter] = max;

最后会出现同样的问题;

*(result + counter++ * sizeof(void *)) = NULL;

应该是

result[counter] = NULL;

此外,您应该检查realloc的结果是否为NULL,如果是,请退出该计划。