стек поврежден после memcpy - PullRequest
       25

стек поврежден после memcpy

1 голос
/ 03 февраля 2012

Я хочу скопировать объект и отправить его по сети с помощью 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 Стек вокруг переменной «держатель данных» поврежден.

Может кто-нибудь помочь мне с этим?

Ответы [ 3 ]

2 голосов
/ 03 февраля 2012

Ваша переменная 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) - это, вероятно, лучший вариант.)

Наконец, как отметил Марк Уилкинс в своем ответе, вам нужно удалять массивы с delete[], а не delete, чтобы избежать повреждения кучи.

2 голосов
/ 03 февраля 2012

Я не уверен, что это будет частью проблемы, но delete должно быть:

delete[] dataholder;

Что более важно, вызов ZeroMemory не должен передавать адрес dataholder (& держатель данных) а точнее его значение (на что оно указывает):

ZeroMemory(dataholder ...
0 голосов
/ 03 февраля 2012

Вы перезаписываете стек в своих вызовах memcpy. Причина в том, что вы берете адрес переменной, которая содержит адрес вашего буфера. Все, что вы хотите, это адрес вашего буфера.

Используйте «держатель данных», а не «& держатель данных» в вызовах Zeromemory и memcpy.

...