我想复制一个对象并使用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'周围的堆栈已损坏。
有人可以帮我这个吗?
答案 0 :(得分:2)
我不确定这是否会成为问题的一部分,但delete
应该是:
delete[] dataholder;
更重要的是,ZeroMemory调用不应传递dataholder
(& dataholder)的地址,而应传递其值(它指向的内容):
ZeroMemory(dataholder ...
答案 1 :(得分:2)
您的dataholder
变量是指向大小为backditup
的数组的指针,而不是数组本身。因此,当您执行Zeromemory
和memcpy
来电时,您不应该使用其地址;相反,写:
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”。