[C++] classe array 1d et delete[]

classe array 1d et delete[] [C++] - C++ - Programmation

Marsh Posté le 20-11-2009 à 09:30:44    

Bonjour à tous,
 
Je galère sur un problème de gestion de mémoire et je n'arrive pas à trouver la solution.
 
J'ai une classe Array_1D, qui remplit grosso modo le rôle de la classe standard Vector.
Dans cette classe qui est un template, j'ai donc un pointeur vers le bloc mémoire contenant l'ensemble des données :
 

Code :
  1. template <class type>
  2. class      Array_1D
  3. {
  4. private:
  5.    int  number_of_elements;
  6.    int  last_element;
  7.    type* array;
  8.       .............


 
Pour rajouter des éléments dans cette classe de stockage, j'ai une fonction extend_array, prenant en paramètre le nombre d'élément à ajouter :

Code :
  1. template <class type>
  2. type&
  3. Array_1D<type>::extend_array(const int& number_of_elements_to_add)
  4. {
  5.    int  new_number_of_elements =number_of_elements + number_of_elements_to_add;
  6.  if(new_number_of_elements > 0)
  7.  {
  8.   if(array != NULL)
  9.   {
  10.    type* buffer     =new type[new_number_of_elements];
  11.          memcpy(buffer, array, sizeof(type) * number_of_elements);
  12.      delete[]   array;
  13.      array    =buffer;
  14.   }
  15.   else
  16.      array    =new type[new_number_of_elements];
  17.  }
  18.      number_of_elements =new_number_of_elements;
  19.      last_element  =number_of_elements - 1;
  20.      return    array[last_element];
  21. }


 
Le problème vient du delete[].  Il fait planter mon appli. Si je le mets en commentaire ça fonctionne, mais bien évidemment j'ai de grosses fuites mémoire.
Je ne comprends pas d'où vient le problème, auriez-vous une idée ?
 
Je vous remercie par avance !!

Reply

Marsh Posté le 20-11-2009 à 09:30:44   

Reply

Marsh Posté le 20-11-2009 à 09:57:42    

1/ Pourquoi ne pas utiliser vector?
2/ Les constructeurs de copie qui ne sont pas executes, ca peut expliquer beaucoup
3/ Un probleme de crash avec un delete, c'est souvent une corruption et celle-ci peut avoir sa cause a peut pres n'importe quand avant.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 20-11-2009 à 10:04:52    

Il est vrai que j'aurai pu utiliser vector, mais pour plusieurs raisons j'ai préféré codé ma propre classe.
 
Pourrais-tu expliciter la notion de constructeur de copy dans le cas qui m'intéresse ? Tu parles de l'instruction memcpy ?


---------------
http://www.ryphon-mechanics.com
Reply

Marsh Posté le 20-11-2009 à 10:10:31    

Si je remplace memcpy par une boucle qui copie les éléments 1 par 1, ça fonctionne :
 

Code :
  1. for(int i = 0;i < number_of_elements;i++)
  2.     buffer[i] =array[i];


 
Je ne comprends pas pourquoi cela fonctionne mieux, d'autant plus que l'utiliser de memcpy permet d'optimiser  les performances, et c'est ce que je recherche...


---------------
http://www.ryphon-mechanics.com
Reply

Marsh Posté le 20-11-2009 à 10:22:41    

*memcpy copie des tas d octets
*buffer[i] = array[i] appelle le constructeur type( const type& ) ...  du coup c est ce que tu dois faire. Si tu veux de meilleures perfs ensuite tu peux envisager de specialiser ton template pour certains types ou le memcpy ne pose pas probleme
*utilise vector

Message cité 1 fois
Message édité par chewif le 20-11-2009 à 10:23:43
Reply

Marsh Posté le 20-11-2009 à 11:43:00    

Vel-Ryphon a écrit :

Il est vrai que j'aurai pu utiliser vector, mais pour plusieurs raisons j'ai préféré codé ma propre classe.


Par plusieurs tu veux parler du fait que ta classe sera bugguée, moins performante, moins générique et moins interoperabel que std::vector ? ou bien du fait que tu n'as que ça à faire de ton temps de reinventer l'eau froide ? ou bien ta boite est un de ces dinosaures qui crois la STL est mal faite ?

Message cité 1 fois
Message édité par Joel F le 20-11-2009 à 11:44:33
Reply

Marsh Posté le 20-11-2009 à 11:45:04    

chewif a écrit :


*buffer[i] = array[i] appelle le constructeur type( const type& ) ...  du coup c est ce que tu dois faire. Si tu veux de meilleures perfs ensuite tu peux envisager de specialiser ton template pour certains types ou le memcpy ne pose pas probleme


 
std::copy fait deja cette optimisation :)

Reply

Marsh Posté le 20-11-2009 à 13:57:23    

Joel F a écrit :


Par plusieurs tu veux parler du fait que ta classe sera bugguée, moins performante, moins générique et moins interoperabel que std::vector ? ou bien du fait que tu n'as que ça à faire de ton temps de reinventer l'eau froide ? ou bien ta boite est un de ces dinosaures qui crois la STL est mal faite ?


 
parce-que je programme pour mon loisir, que j'aime programmer même des trucs qui ont déjà été fait, et que j'aime bien me casser les dents sur un problème, car une fois résolu j'ai appris des choses :-).


---------------
http://www.ryphon-mechanics.com
Reply

Marsh Posté le 20-11-2009 à 14:24:57    

sauf que la c'est contre-productif mais c'est pas grave ...

Reply

Marsh Posté le 20-11-2009 à 16:06:57    

Joel F a écrit :

sauf que la c'est contre-productif mais c'est pas grave ...


 
Pourquoi être toujours négatif ? Ma question ne portait pas sur la pertinence de ma classe, mais sur un point technique précis d'une méthode. Je ne cherche pas à être productif dans mes loisirs, je cherche à me faire plaisir, c'est le but de tout loisir.


---------------
http://www.ryphon-mechanics.com
Reply

Marsh Posté le 20-11-2009 à 16:06:57   

Reply

Marsh Posté le 20-11-2009 à 17:04:50    

Le probleme que je vois -- encore plus que de perdre ton temps a reinventer la roue -- c'est que tu sautes les etapes.  Ecrire des templates mais ne pas comprendre directement quel est le fond du probleme quand on t'indique que tu n'utilises pas les constructeurs de copie, indique pour moi que tu ne maitrises pas encore les bases.  Ecrire des templates -- reinventant la roue ou non -- est premature.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 20-11-2009 à 17:16:54    

Toujours est-il que je ne comprends pas pourquoi le memcpy pose problème, puisqu'à partir du moment où mon array est alloué avec un new[], la mémoire est forcément contigue, et de ce fait le delete[] ferait son office correctement...


---------------
http://www.ryphon-mechanics.com
Reply

Marsh Posté le 20-11-2009 à 17:55:16    

non. Si tu fais un tableau d'objet, ca copie doit copier les objets en appelant leur constructeur de copie qui peuvent avoir des effets de bords. Si tu copie des objets bits à bits, tu t'expose à de sacrée deconvenue.
 
Exemple, fait un array<array> et tu verras :€

Reply

Marsh Posté le 20-11-2009 à 18:47:17    

D'accord, c'est plus clair maintenant. Merci pour ces explications, et dommage que l'optimisation que le memcpy m'aurait apportée ne fonctionne pas :(.


---------------
http://www.ryphon-mechanics.com
Reply

Marsh Posté le 20-11-2009 à 19:51:06    

elle fonctionnera si tu utilises std::copy ... car elle se charge de faire ça
 
Et sidenote, tu te fout des perfs quant que t'as pas bencher :o

Reply

Marsh Posté le 20-11-2009 à 20:12:04    

Hum, je dirai qu'en plus, c'est pas du C que tu fais, mais du C++. Un tableau alloué par new "contient" des information caché (bon c'est pas vraiment lui qui les as), qui fait que tu n'as pas a faire de Delete[n] mais juste un Delete[]. Je pense que dans ton cas il cherche désespérément à desalloué le tout premier tableau que tu as fais...  
 
En plus tu as déplacé des éléments sans leur signifié qu'ils étaient déplacer...
 
Mais je suis vraiment pas sur de ça. Regarde un coup le désassemble ou les logs...

Reply

Marsh Posté le 20-11-2009 à 20:16:03    

non delete[] est la forme correcte pr la desallocation d'un tableau alloué par new ...
et y a qu'en russie stalinienne ou on desassemble son code pour chercher des erreurs ...


Message édité par Joel F le 20-11-2009 à 20:16:23
Reply

Marsh Posté le 20-11-2009 à 20:19:58    

Erf, et on bazarde pas des données en écrasant un tableau dynamique comme ça ?

Reply

Marsh Posté le 20-11-2009 à 20:52:05    

euh non, lis la doc de delete[]

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed