2010-11-09 4 views
0

Cela fait longtemps que je n'ai pas programmé en C++, mais j'ai récemment écrit une petite fonction C++ et j'ai un peu de mal. La fonction renvoie une structure, Result, qui contient des chaînes. Je pensais avoir alloué de la mémoire pour les chaînes, mais jsonResult est parfois partiellement écrasé.Problème de mémoire alloué C++

//The structs 
    struct Interp { 
     int score; 
     char* sentence; 
     char* jsonResult; 
    }; 

    struct Result { 
     int resultCode; 
     char* errorMessage; 
     Interp interp; 
    }; 

...

//Inside the function 
    Result result; 

    //Store decode 
    const char* jsonResult,* sentence; 
    if (result.resultCode == -1) 
    { 
      LVInterpretation interp = port.GetInterpretation(voiceChannel, 0); 

      result.interp.score = interp.Score(); 
      sentence = interp.InputSentence(); 
      jsonResult = interp.ResultData().Print(SI_FORMAT_ECMA); 
    } 

    //Allocate memory for strings 
    result.interp.jsonResult = new char[strlen(jsonResult) + 1]; 
    strcpy(result.interp.jsonResult, jsonResult); 

    result.interp.sentence = new char[strlen(sentence) + 1]; 
    strcpy(result.interp.sentence, sentence); 

    result.errorMessage = new char[strlen(errorMessage) + 1]; 
    strcpy(result.errorMessage, errorMessage); 

    return result; 

Autres informations: J'observe tout cela derrière le python liant que je l'ai écrit, en utilisant ctypes. Ne pensez pas que cela affecte vraiment quelque chose.

+3

L'utilisation de 'std :: string' vous éviterait beaucoup de maux de tête. –

+0

Vous ne montrez pas assez de code pour que nous devinions où le problème pourrait être. En particulier, le code qui libère la mémoire que vous avez allouée est absent de cet affichage. –

+0

Je ne sais pas vraiment quel autre code montrer. C'est le seul code qui traite de ces chaînes. Je me demande juste si j'ai correctement alloué de la mémoire pour les chaînes. Si c'est le cas, le problème est probablement lié à ma liaison python. – veered

Répondre

1

je mettrais de l'argent sur votre problème étant ici:

jsonResult = interp.ResultData().Print(SI_FORMAT_ECMA); 

qui « possède » le tableau de char * retourné par impression()? Peut-être essaie-t-il de renvoyer un pointeur vers une mémoire hors de portée?

exemple:

char* badFunction(void) 
    { 
    char test[100]; 
    strcpy(test,"This is really clever"); // oh, yeah? 
    return test; // returns pointer to data that's out of scope 
    } 

Une autre chose. Affectez des pointeurs NULL à phrase, jsonResult, etc lorsque vous les déclarez. Sinon, vous pourriez finir par strcpy() avec des données non initialisées,

+0

Cela me semble juste, car jsonResult est le seul avec lequel j'ai eu des problèmes. Une bibliothèque extérieure le possède. Comment pourrais-je assurer que les données ne sont pas hors de portée? – veered

+0

@Veered: Si Print() renvoie vraiment char *, la documentation de Print() * DOIT * spécifier la sémantique de la propriété. La seule approche valide (mais laide) est que Print() alloue la mémoire et demande à l'appelant de la supprimer par la suite. Si Print() a le bug que je décris, vous êtes ... – Roddy

+0

Ok, on dirait que j'ai manqué une partie des docs. La chaîne renvoyée par Print() est libérée lorsque l'objet renvoyé par ResultData() est libéré. J'ai donc créé une fuite de mémoire, mais la chaîne ne devrait-elle pas rester en sécurité jusqu'à ce que je la transfère? – veered

4

Utilisez std::string. Vous ne le regretterez pas.

+0

Je ne peux pas. Ctypes nécessite un caractère *. – veered

+2

Vous pouvez fournir un caractère * via la méthode std :: string :: c_str. –

+0

Ne devrais-je toujours pas allouer de la mémoire pour le char *? Parce que l'allocation de mémoire est la source de mes problèmes. – veered

0

Couple de choses:

  1. Que signifie "partiellement écrasé" signifie? Comment sais-tu cela? c'est-à-dire quelle est votre sortie attendue par rapport à ce que vous voyez?

  2. Il est pas vraiment clair comment result.resultCode est réglé sur -1 (ou si elle est du tout), et si elle est définie, comment la mémoire allouée en se interp.InputSentence() et interp.ResultData().Print(SI_FORMAT_ECMA)? Je vous suggère que votre problème est là

Le reste du code devrait fonctionner aussi longtemps que jsonResult et sentence contiennent des chaînes terminées par null valide.

+0

1. Je m'attendrais à quelque chose comme: '[{score: 880, mot: "drum"}]', mais obtiendrait '[{score: 880, worPORT FERMÉ'. Ou quelque chose comme ça. 2. J'ai défini resultCode sur -1 auparavant, je ne voulais pas montrer toute la fonction, parce que c'est ~ 200 lignes.Et je ne suis pas sûr de la façon dont la mémoire est allouée pour les fonctions interp. * Car celles-ci sont une bibliothèque externe. – veered