我正在编写一个接收数组(任何类型)的泛型函数,并在该数组中找到最大值(根据指定的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;
}
但它仍然是同样的问题......
感谢。
答案 0 :(得分:4)
你的'result'数组是一个指针数组,而不是一个项目数组(int
,char
等)。因此,您对此数组的索引是错误的: -
*(result + counter++
* sizeOfElement
) = max;
上面突出显示的项目不是必需的,指针算术已经考虑了元素的大小(在这种情况下是void *
)。
你遇到的另一个问题是你的记忆分配: -
result = (void **) malloc(sizeOfElement)
和
realloc(result, (counter + 1) * sizeOfElement)
您没有分配element
类型的数组,而是分配pointers to elements
(void *
)数组,因此不需要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
,如果是,请退出该计划。