2012-02-02 4 views
1

Je veux copier un objet et l'envoyer sur le réseau avec winsock, mais il y a un problème. Je détruis la pile si je copie un objet dans un tableau de caractères sur le tas. Voici mon code:pile corrompue après 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(); 

Le code fonctionnera correctement, mais quand je le compiler en mode débogage j'obtenir à la fin:
http://imageshack.us/photo/my-images/839/errormnr.png/

Run-Time Échec de la vérification # 2 Stack autour de la variable 'détenteur de données' était corrompu.

Quelqu'un peut-il m'aider?

+1

Changez char * dataholder = nouveau char [sizeof (backditup)]; 'en' char * dataholder = nouveau char [sizeof (backditup)](); 'et il n'y a aucun besoin de 'ZeroMemory'. Ce n'est pas C, c'est C++, vous devriez donc utiliser des idiomes C++. – ildjarn

Répondre

2

votre variable dataholder est un pointeur sur un tableau de la taille backditup, pas le tableau lui-même. Ainsi, lorsque vous effectuez les appels Zeromemory et memcpy, vous ne devez pas prendre son adresse; au lieu, écrire:

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

sans &. De même, lorsque vous copiez les données en arrière, vous voulez:

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

Et enfin, vous devez faire la même solution dans le second Zeromemory appel - bien que, puisque vous supprimez le tableau immédiatement après cet appel, il n'y a vraiment aucun intérêt à avoir cet appel du tout.

La taille du second appel Zeromemory est erronée pour la même raison; sizeof(dataholder) est la taille du pointeur, pas le tableau vers lequel il pointe. Si vous ne supprimez pas simplement cet appel entièrement, vous devez soit utiliser sizeof(backditup) ici pour la cohérence avec la déclaration, ou mieux encore, déclarer une variable pour contenir la longueur du tableau de détenteurs de données et l'utiliser de manière cohérente. (Vous pouvez aussi utiliser la taille du type de données, sizeof(testclass) -. Qui est probablement la meilleure option)

Enfin, comme Mark Wilkins a noté dans sa réponse, vous devez supprimer des tableaux avec delete[], non delete, pour éviter d'endommager le tas.

+1

Le premier appel 'ZeroMemory' ne sert à rien non plus, étant donné qu'un simple'() 'fera exactement la même chose. – ildjarn

+0

@ildjarn: Excellent point! –

+0

Merci, cela a résolu l'erreur! – Dagob

2

Je ne suis pas sûr si ce serait une partie du problème, mais le delete devrait être:

delete[] dataholder; 

Plus important encore, l'appel ZeroMemory ne doit pas être passer l'adresse de dataholder (& DataHolder), mais plutôt sa valeur (ce qu'il pointe vers):

ZeroMemory(dataholder ... 
+0

Bonne prise! Je ne pense pas que 'delete 'soit le problème à l'origine de cette erreur particulière, mais cela corrompra les choses dans le tas, pas dans la pile. –

+0

Merci, ça marche maintenant. – Dagob

+0

La différence entre 'delete' et' delete [] 'est-elle vraiment pertinente pour les" anciennes données "? Sûrement cela joue un rôle si des destructeurs sont impliqués, mais sinon ...? – krlmlr

0

Vous écrasez la pile dans vos appels memcpy. La raison en est que vous prenez l'adresse de la variable qui contient l'adresse de votre tampon. Tout ce que vous voulez, c'est l'adresse de votre tampon.

Utilisez "dataholder" et non "& dataholder" dans les appels Zeromemory et memcpy.

Questions connexes