2012-02-02 152 views
1

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

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堆栈周围的变量'数据持有者'被破坏。

有人可以帮助我吗?

+1

将'char * dataholder = new char [sizeof(backditup)];'改为'char * dataholder = new char [sizeof(backditup)]();'不需要任何'ZeroMemory'。这不是C,它是C++,所以你应该使用C++习惯用法。 – ildjarn 2012-02-02 21:58:44

回答

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) - 这可能是最好的选择)

最后,正如马克·威尔金斯在他的回答指出,需要用delete[],不delete删除阵列,以避免破坏堆。

+1

第一个'ZeroMemory'调用没有意义,因为一个简单的'()'可以完成同样的事情。 – ildjarn 2012-02-02 22:03:49

+0

@ildjarn:极好的一点! – 2012-02-02 22:06:13

+0

谢谢,这解决了错误! – Dagob 2012-02-02 22:06:24

2

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

delete[] dataholder; 

更重要的是,ZeroMemory呼叫不应通过dataholder(& dataholder)的地址,而是其值(它指向于):

​​
+0

好抓!我不认为'delete'是造成这个特定错误的问题,但这会破坏堆中的东西,而不是堆栈。 – 2012-02-02 21:57:06

+0

谢谢,它现在有效。 – Dagob 2012-02-02 22:08:58

+0

'delete'和'delete []'与“普通旧数据”真正相关吗?如果涉及析构函数,它肯定会发挥作用,否则......? – krlmlr 2012-02-02 22:38:34

0

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

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