堆栈在memcpy之后损坏了

时间:2012-02-02 21:50:17

标签: c++ object visual-studio-2005 runtime-error memcpy

我想复制一个对象并使用winsock通过网络发送它,但是有一个问题。如果我将对象复制到堆上的字符数组,我会销毁堆栈。这是我的代码:

testclass backditup;       //This is an object with information
testclass restorenaarhier; //I will copy it to this object

backditup.setvalues(100,100);
restorenaarhier.setvalues(0,0);

char * dataholder = new char[sizeof(backditup)];  //This is the data holder
ZeroMemory(&dataholder,sizeof(backditup));

memcpy(&dataholder,&backditup,sizeof(backditup)); //Save it to the char[]

//Sending it over the network
//resieving the object

//Store the data on the same object 
memcpy(&restorenaarhier,&dataholder,sizeof(restorenaarhier));

//deleting the data holder
ZeroMemory(&dataholder,sizeof(dataholder));
delete dataholder;

//output the code
restorenaarhier.echo();

代码将正常工作,但是当我在调试模式下编译它时,我得到了结论:
http://imageshack.us/photo/my-images/839/errormnr.png/

运行时检查失败#2变量'dataholder'周围的堆栈已损坏。

有人可以帮我这个吗?

3 个答案:

答案 0 :(得分:2)

我不确定这是否会成为问题的一部分,但delete应该是:

delete[] dataholder;

更重要的是,ZeroMemory调用不应传递dataholder(& dataholder)的地址,而应传递其值(它指向的内容):

ZeroMemory(dataholder ...

答案 1 :(得分:2)

您的dataholder变量是指向大小为backditup的数组的指针,而不是数组本身。因此,当您执行Zeromemorymemcpy来电时,您不应该使用其地址;相反,写:

ZeroMemory(dataholder,sizeof(backditup));
memcpy(dataholder,&backditup,sizeof(backditup));

没有&。同样,当您复制数据时,您需要:

memcpy(&restorenaarhier,dataholder,sizeof(restorenaarhier));

最后,您需要在第二次Zeromemory调用中进行相同的修复 - 但是,由于您在该调用之后立即删除该数组,因此完全没有必要进行该调用。

出于同样的原因,第二次Zeromemory电话的大小是错误的; sizeof(dataholder)是指针的大小,而不是它指向的数组。如果你不是简单地完全删除这个调用,你应该在这里使用sizeof(backditup)来保证与声明的一致性,或者更好的是,声明一个变量来保存数据持有者数组的长度并一致地使用它。 (或者您可以使用数据类型的大小sizeof(testclass) - 这可能是最佳选择。)

最后,正如Mark Wilkins在答案中指出的那样,你需要删除delete[]而不是delete的数组,以避免破坏堆。

答案 2 :(得分:0)

您正在覆盖memcpy调用中的堆栈。原因是您正在获取保存缓冲区地址的变量的地址。你想要的只是缓冲区的地址。

在Zeromemory和memcpy调用中使用“dataholder”而不是“& dataholder”。

相关问题