C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

problème sur un delete

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
cyan
Guest





PostPosted: Wed Aug 10, 2005 11:43 am    Post subject: problème sur un delete Reply with quote



bonjour,

j'ai une erreur qui se produit sur un delete et je ne comprends pas.

ma méthode prends en paramètre une adresse email, celle-ci doit se
charger de l'éliminer d'une liste d'adresse email( celle-ci est un
membre de ma classe).
Seul dans le cas où l'adresse à supprimer est en tête de liste, la
méthode ne plante pas.

merci d'avance pour votre aide.

yann

voici ma méthode


STDMETHODIMP COutlookEvents::modifyAddressees(CHAR* email_account)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

// TODO : ajoutez ici votre code d'implémentation
char * found = NULL;
char * next_email = NULL;
char * tmp = NULL;

std::cerr<<"modifyAddressees"<
if( email_account )
{
/// recherche email_account dans destinataire
found = strstr(destinataire, email_account);

if( found )
{
std::cerr<<"trouvé"< next_email = strchr(found, ';');

std::cerr<
/// email_account est en tête de liste ?
if( found == destinataire )
{
std::cerr<<"trouvé 2 "<
if( next_email )
{
std::cerr<<"en tete de liste"< next_email++;
*(next_email-1) = '';

std::cerr<<"avt new"< destinataire = new char[strlen(next_email)+1];

std::cerr<<"apres new avt strcpy"< strcpy(destinataire, next_email);

std::cerr<<"apres strcpy"<
}
else
delete destinataire;

}
else
{
/// y a-t-il d'autres adresses emails après celle à supprimer ?
if( next_email )
{
std::cerr<<"au milieur de la liste"<
tmp = destinataire;

/// séparation entre l'adresse email à supprimer et les autres
emails à garder( qui sont avant )
*(found-1) = '';

///positionnement sur le 1er caractere de l'adresse mail
next_email++;

/// séparation entre l'adresse email à supprimer et les autres
emails à garder( qui sont après )
*(next_email-1) = '';

destinataire = new char[strlen(tmp)+strlen(next_email)+3];

strcpy(destinataire, tmp);

/// raccrochage
strcat(destinataire,";");
strcat(destinataire, next_email);

}
else /// email_account est en fin de liste
{
std::cerr<<"en fin de liste"< *(found-1) = '';


}

}/// end if( found == destinataire )


}/// end if( found )
std::cerr<
if( found )
std::cerr<<"found : "<< found <
if( tmp )
std::cerr<<"tmp : "<< tmp <
if( next_email )
std::cerr<<"next : "<< next_email <
std::cerr<<"avant delete"< delete found; ////PLANTAGE
std::cerr<<"apres delete"< }
return S_OK;
}

Back to top
Fabien LE LEZ
Guest





PostPosted: Wed Aug 10, 2005 12:36 pm    Post subject: Re: problème sur un delete Reply with quote



On 10 Aug 2005 04:43:07 -0700, "cyan" <yann_chaysinh (AT) yahoo (DOT) fr>:

Quote:
j'ai une erreur qui se produit sur un delete et je ne comprends pas.

Franchement, ton code me paraît trop compliqué pour avoir une chance
de fonctionner.
Et comme je n'ai aucune idée de l'endroit où se trouve le new qui va
avec le delete, je ne risque pas de pouvoir t'aider.

Note par ailleurs que "delete" et "new[]" sont incompatibles --
delete[] va avec new[] et delete avec new.
Ou plutôt, "delete" correspond à "new" et... c'est tout. AMHA, il se
passera un sacré bout de temps avant que tu aies un usage légitime de
new[].

Tu essaies apparemment d'utiliser des chaînes de caractères, mais en
C, avec des char*. Dans le meilleur des cas, c'est pénible à écrire
correctement, pénible à lire, pénible à maintenir. (Pour le pire des
cas, remplacer "pénible" par "impossible".)

En C++, une chaîne de caractère, c'est un std::string. Pas de malloc,
de new[] ou de delete[], pas de problème pour gérer la taille, ni de
difficultés à copier.

D'autre part, j'ai l'impression que tu utilises une chaîne pour
stocker une liste de chaînes séparées par un espace.
Ce serait beaucoup plus simple de faire carrément un tableau de
chaînes :

Quote:
STDMETHODIMP COutlookEvents::modifyAddressees(CHAR* email_account)

Dans quelles limites peux-tu modifier ce prototype ?

L'idéal serait :

STDMETHODIMP COutlookEvents::modifyAddressees
(std::string const& email_account)

Si ce n'est pas possible, une solution parfaitement acceptable :

STDMETHODIMP COutlookEvents::modifyAddressees
(char const* email_account)

Si vraiment tu ne peux rien changer, au moins assure-toi que le
paramètre ne sera pas modifié :

STDMETHODIMP COutlookEvents::modifyAddressees
(CHAR* PARAM_email_account)
{
std::string email_account (PARAM_email_account);
// suite de la fonction...
}



Back to top
Arnaud Meurgues
Guest





PostPosted: Wed Aug 10, 2005 12:41 pm    Post subject: Re: problème sur un delete Reply with quote



cyan wrote:

Quote:
j'ai une erreur qui se produit sur un delete et je ne comprends pas.

Je pense que vous allez mieux comprendre si je vous pose la question
suivante :
Quelle est la taille du bloc mémoire que vous voulez libérer ?

found pointe au milieu d'un bloc mémoire. Il ne correspond donc pas à
l'adresse d'un bloc alloué. Vous ne pouvez pas choisir de désallouer une
partie d'un bloc mémoire. De plus, même si c'était possible, il n'y a
aucun moyen de savoir quelle taille de bloc vous voulez désallouer (la
désallocation ne s'occupe pas du contenu de ce qui est désallouer, et le
fait qu'il y a un '' ne l'intéresse en rien).

Donc, on ne peut désallouer un bloc qu'avec l'adresse qui a été
retrournée lors de son allocation, et c'est tout le bloc qui est
désalloué. C'est pourquoi le delete ne plante pas lorsque l'adresse est
en tête de liste : found est alors l'adresse de début du bloc.

Bref, ce qu'il faut faire, alors, c'est allouer un bloc de la bonne
taille, y recopier ce que vous souhaitez garder, puis deleter l'ancien
bloc (avec l'adresse de début de bloc, c'est-à-dire destinataire).

Un manière simple de faire serait d'itérer sur toutes les adresses de
destinataire et de ne recopier dans le résultat que les adresses
différentes de celle à supprimer. C'est un peu moins efficace (o(n) au
lieu de o(n/2)), mais probablement beaucoup plus clair à lire, et ça
couvre le cas où la même adresse serait présente deux fois.


--
Arnaud

Back to top
Fabien LE LEZ
Guest





PostPosted: Wed Aug 10, 2005 12:41 pm    Post subject: Re: problème sur un delete Reply with quote

On 10 Aug 2005 04:43:07 -0700, "cyan" <yann_chaysinh (AT) yahoo (DOT) fr>:

Quote:
ma méthode prends en paramètre une adresse email, celle-ci doit se
charger de l'éliminer d'une liste d'adresse email( celle-ci est un
membre de ma classe).

Voici comment j'écrirais une telle classe :

class Bidule
{
public:
void SupprimerAdresse (std::string const& adresse_a_supprimer);

private:
typedef std::vector<std::string> ListeAdresses;
ListeAdresses liste_adresses;
};

void Bidule::SupprimerAdresse (std::string const& adresse_a_supprimer)
{
ListeAdresses::iterator it_adresse_a_supprimer=
std::find (liste_adresses.begin(), liste_adresses.end(),
adresse_a_supprimer);

if (it_adresse_a_supprimer == liste_adresses.end())
{
// On vire l'adresse du tableau
liste_adresses.erase (it_adresse_a_supprimer);
}
else
{
// L'adresse n'était pas dans le tableau
}
}

Note : ça paraît un peu long, mais c'est juste parce que j'ai tendance
à employer des identifiants à rallonge. Ce qui n'est pas forcément un
mal, d'ailleurs.




Back to top
Arnaud Meurgues
Guest





PostPosted: Wed Aug 10, 2005 12:47 pm    Post subject: Re: problème sur un delete Reply with quote

Fabien LE LEZ wrote:

Quote:
void Bidule::SupprimerAdresse (std::string const& adresse_a_supprimer)
{
ListeAdresses::iterator it_adresse_a_supprimer=
std::find (liste_adresses.begin(), liste_adresses.end(),
adresse_a_supprimer);

if (it_adresse_a_supprimer == liste_adresses.end())

C'est pas !=, plutôt ?

Quote:
{
// On vire l'adresse du tableau
liste_adresses.erase (it_adresse_a_supprimer);
}
else
{
// L'adresse n'était pas dans le tableau
}
}

Par ailleurs, effectivement, pour deleter un tableau de char, c'est
delete[] qu'il faut utiliser. Mais attention, si ce tableau a été alloué
par malloc, alors il faut utiliser free et non delete[].

--
Arnaud

Back to top
Fabien LE LEZ
Guest





PostPosted: Wed Aug 10, 2005 12:50 pm    Post subject: Re: problème sur un delete Reply with quote

On Wed, 10 Aug 2005 14:47:51 +0200, Arnaud Meurgues
<news.arnaud (AT) meurgues (DOT) non.fr.invalid>:

Quote:
if (it_adresse_a_supprimer == liste_adresses.end())

C'est pas !=, plutôt ?

Effectivement. C'était pour voir si tu suivais.


Back to top
cyan
Guest





PostPosted: Wed Aug 10, 2005 3:21 pm    Post subject: Re: problème sur un delete Reply with quote

merci pour vos remarques et réponses, j'utiliserai dorénavant le type
string

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.