所以我终于能够让测试功能正常工作,但我没有在链接列表的这个mergesort上传递测试函数。经过几个小时的调试后,由于出现以下溢出错误,它会变得更糟。
ConsoleApplication2.exe中0x01041719处的未处理异常:0xC00000FD:堆栈溢出(参数:0x00000001,0x006E2FC0)。
#include <stdio.h>
#include <stdlib.h>
struct listnode {struct listnode * next; int key; };
struct listnode * merge(struct listnode * left, struct listnode * right)
{
struct listnode * right2;
if (left == NULL)
return right;
if (right == NULL)
return left;
if (left->key < right->key)
{
right2 = left;
right2->next = merge(left->next, right);
}
else
{
right2 = right;
right2->next = merge(left, right->next);
}
return right2;
}
struct listnode *sort(struct listnode * a)
{
struct listnode * left, * right;
if (a== NULL || a->next == NULL)
return a;
left = a; right = a->next;
while (right!= NULL && right->next != NULL)
{
left = left->next;
right = right->next->next;
}
right = left->next;
left->next = NULL;
return merge(sort(a), sort(right));
}
int main()
{
long i;
struct listnode *node, *tmpnode, *space;
space = (struct listnode *) malloc(500000 * sizeof(struct listnode));
for (i = 0; i < 500000; i++)
{
(space + i)->key = 2 * ((17 * i) % 500000);
(space + i)->next = space + (i + 1);
}
(space + 499999)->next = NULL;
node = space;
printf("\n prepared list, now starting sort\n");
node = sort(node);
printf("\n checking sorted list\n");
for (i = 0; i < 500000; i++)
{
if (node == NULL)
{
printf("List ended early\n");
}
if (node->key != 2 * i)
{
printf("Node contains wrong value\n");
}
node = node->next;
}
printf("Sort successful\n");
return 0;
}
答案 0 :(得分:0)
这是因为递归调用太多(在这种情况下:500 000)。尽可能减少列表大小(很少发生)或找到用迭代替换递归的方法。您可以使用自己的堆栈结构来存储指针并使用循环而不是递归调用函数。
假设指针大小是4个字节,在函数和EIP中有3个指针,在最后一次递归调用时,消耗的内存将是500 000 * 4 * 4(大于7.5MB)。你的程序堆栈大小是否大于7.5MB?
顺便说一句,考虑使500000为常数avoid using magic number。