2012-12-06 87 views
0

我在写一个函数,该函数应该使用合并排序对数组进行排序。到目前为止,我有两个功能:检测到合并排序堆损坏

template <typename Item, typename SizeType> 
void merge_sort(Item data[], SizeType size) { 
SizeType size1, size2; 
if(size > 1) { 
    size1 = size/2; 
    size2 = size - size1; 
    merge_sort(data,size1); 
    merge_sort((data+size1),size2); 

    merge(data,size1,size2); 
} 
} 

和:

template <typename Item, typename SizeType> 
void merge(Item data[], SizeType size1, SizeType size2) { 
Item* temp; 
SizeType copied = 0; 
SizeType copied1 = 0; 
SizeType copied2 = 0; 

temp = new Item[size1 + size2]; 

while(copied1 < size1 && copied2 < size2) { 
    if(data[copied1] < (data + size1)[copied2]) 
     temp[++copied] = data[++copied1]; 
    else 
     temp[++copied] = (data + size1)[++copied2]; 
} 

while (copied1 < size1) 
    temp[++copied] = data[++copied1]; 
while (copied2 < size2) 
    temp[++copied] = (data + size1)[++copied2]; 

for(SizeType i = 0; i < size1 + size2; ++i) 
    data[i] = temp[i]; 
delete [] temp; 
} 

当我尝试但是运行程序,我得到一个调试错误说,堆是一个正常的块之后和损坏CRT检测到应用程序在堆缓冲区结束后写入内存。任何人都可以解释这是什么意思,我怎么能解决它?

+0

您的代码缺少文档注释。 –

回答

2

您使用的值之前,正在增加......所以,基本上使检查过时...

使用copied++来代替。

您需要后增加运算符,因为如果在使用它之前增加运算符,则会超出界限。 Increment and decrement operators

+0

这可以解释它。我总是忘记何时评估一元运算符。非常感谢! –

2

你的意思是你的增量是后增量而不是增量?例如:

temp[copied++] = (data + size1)[copied2++]; 

通过预增量,在第一次循环,当copied20,您在访问(data + size1)[1]。当copied2到达您分配的内存的末尾时,您正在访问末尾的一个。

为了避免这种情况,我建议不要增加子表达式。写入可能会令人困惑。

1

如果复制= 0和copied1 = 0,则线

温度[++复制] =数据[++ copied1];

会产生

温度[1] =数据[1];

因为前缀++这里有最高优先权