2010-07-10 7 views
-1

J'essaie d'apprendre C++, dans le processus j'ai essayé d'écrire une fonction qui obtient deux pointeurs de char et concaténer le second au premier (je sais qu'il y a strcat pour ce).
Mais - ce que je veux accomplir est de modifier le premier pointeur de paramètre afin qu'il pointe vers le résultat. pour cette raison j'ai utilisé une référence au pointeur dans le premier paramètre.Libération de mémoire dans le problème C++ (Visual Studio 2010)

Avant de revenir à la fonction, je souhaite libérer la première mémoire de paramètres, mais j'obtiens une erreur.

Voici le code:

void str_cat(char*& str1, char* str2) 
{ 
if (!str1) 
{ 
    str1 = str2; 
    return; 
} 
if (!str2) 
    return; 
char * new_data = new char[strlen(str1) + strlen(str2) +1]; 
char * new_data_index = new_data; 
char * str1_index = str1; 
char * str2_index = str2; 

while(*str1_index) 
    *new_data_index++ = *str1_index++; 
while(*str2_index) 
    *new_data_index++ = *str2_index++; 
*new_data_index = NULL; 

delete str1; //ERROR HERE (I also tried delete[] str1) 

str1 = new_data; 
} 

Je ne comprends pas pourquoi.
Des suggestions?

Merci,
Itay \

EDIT Voici comment utiliser la fonction

char * str1 = NULL; 
char * str2 = NULL; 
str_cat(str1, "abc"); 
str_cat(str2, "def"); 
str_cat(str1, str2); 
+0

Comment le code appelant crée-t-il le tampon transmis? –

+5

'J'essaie d'apprendre C++', puis j'utilise 'std :: string' à la place des chaînes de style C. –

+0

@Georg Fritzsche - J'ai essayé d'utiliser str_cat (str1, "aaa") mais je me suis rendu compte que le second paramètre n'était pas alloué en pile mais en pile donc je l'ai changé en nouveau [] ... mais ça ne marche toujours pas. –

Répondre

7

Vous ne pouvez supprimer des choses qui ont été attribuées à nouveau - si votre code ressemblait à ceci:

str_cat("foo", "bar"); 

ce serait illégal. Fondamentalement, votre fonction telle qu'elle est est complètement dangereuse. Une meilleure conception consisterait à renvoyer la nouvelle chaîne via la valeur de retour de la fonction. Encore mieux, oubliez l'idée et utilisez std :: string.

Bien qu'apprendre à utiliser des références aux pointeurs soit une chose louable à faire, sachez qu'ils sont très rarement utilisés en programmation C++. Il vaudrait mieux que vous passiez votre temps à apprendre à utiliser les fonctionnalités de la bibliothèque standard C++.

+0

J'ai modifié la question pour montrer l'utilisation. En tout cas - mon point ici était de passer un pointeur nul et d'obtenir une valeur à l'intérieur. –

+0

@Itay Cela ne fonctionnera toujours pas, pour un certain nombre de raisons. Fondamentalement, c'est une mauvaise conception qui ne peut pas être implémentée en toute sécurité en C++. –

+0

@Neil Butterworth: J'ai eu le problème du mauvais design. Mais encore - pourquoi ça ne marche pas? –

3

Le premier appel à str_cat() résultats en str1 étant attribué l'adresse de la chaîne littérale "abc" que vous avez passé dans.
Avec le troisième appel cela devient un problème que vous essayez de deletestr1 qui, comme Neil l'a souligné, est illégal pour les littéraux de chaîne.

+0

Merci :) Existe-t-il un moyen de tester s'il est légal de libérer un emplacement de mémoire? –

+0

@Itay Non, il n'y en a pas, c'est pourquoi la conception de la fonction est mauvaise. –

+0

@Itay: Non, c'est pourquoi vous ne devriez pas utiliser de telles approches artificielles. Vous pouvez soit exiger que l'appelant passe dans un tampon de taille suffisante ou vous renvoyez toujours un tampon nouvellement alloué et documenter comment il doit être libéré. Ou, comme mentionné précédemment, ne le faites pas du tout - en utilisant 'std :: string',' std :: vector 'et al se débarrasser de tous les problèmes immédiatement. –

Questions connexes