2009-09-12 6 views
4

J'écris un programme C++ qui utilise les bibliothèques RRD qui nécessitent un tableau de 'const char *' pour leurs fonctions. Je pensais que je pouvais simplement déclarer le tableau, puis initialiser chaque élément du tableau, mais en changer un, tous les changements. De toute évidence, il me manque quelque chose. Voici un exemple similaire au code que j'écris (c'est-à-dire qu'il présente le même problème).Tableau de const char *

string intToString(long i) 
{ 
    stringstream ss; 
    string s; 
    ss << i; 
    s = ss.str(); 
    return s; 
} 

int main(){ 
     const char* av[5]; 
     int i = 0; 
     int j = 0; 
     for(i=0;i<5;i++){ 
       j= 0; 
       av[i] = intToString(i).c_str(); 
       for(j=0;j<5;j++){ cout << j << " : " << av[j] << endl;} 
     } 

} 

Toute aide serait appréciée.

+1

exécution de ce code se bloque VS2008, depuis av [5] ne sont pas initialisés, mais son utilisation dans le for (j = 0 ... boucle – quamrana

+0

Side note:. En votre fonction 'intToString', faites juste: return' ss.str(); '. Il n'y a pas besoin de faire une copie, puis retournez la copie de chapeau – GManNickG

Répondre

6

string::c_str renvoie un pointeur temporaire. Vous pouvez utiliser strdup pour obtenir un pointeur persistant.

// don't forget to release memory later 
av[i] = strdup(intToString(i).c_str();); 

Ou vous pouvez affecter tous les tampons manuellement, puis utiliser string::copy pour copier les données de chaîne.

+1

Vrai ... c_str est valide seulement tant que la chaîne qui l'a retourné est. approche serait de stocker le retour de intToString (i) dans un tableau: 'chaîne avs [5];' ... 'avs [i] = intToString (i); av [i] = avs [i] .c_str (); '(bien que je ne vois aucune raison de stocker le char *) –

+0

@Downvoter: Vous voulez faire des commentaires? Lequel n'êtes-vous pas d'accord? –

8

Le const char* retourné par la méthode c_str() d'un std::string des points à un tampon appartenant à la std::string et reste valable uniquement jusqu'au prochain appel à une méthode mutationniste du std::string. Si vous souhaitez conserver le contenu de ce tampon, vous devez copier son contenu ailleurs.

Edit: Sinon, vous pouvez conserver un tableau de std::string pour gérer le stockage des chaînes et stocker temporairement les c_str() pointeurs dans un réseau parallèle de const char* au besoin pour l'interface. Cela évite le besoin de copier les chaînes ou de désallouer manuellement les copies. Dans tous les cas, il est important de ne pas modifier std::string tant que vous détenez la valeur const char* retournée par un appel précédent au c_str().

1

Apporter le tout, vous pouvez écrire votre programme comme celui-ci:

#include <sstream> 
#include <iostream> 

std::string intToString(long i) 
{ 
    std::stringstream ss; 
    std::string s; 
    ss << i; 
    s = ss.str(); 
    return s; 
} 

int main(){ 
    const char* av[5]; // declared but not initialised 
    std::string sav[5]; // std::string has a ctor, so they're initialised 
    for(int i=0;i<5;i++){ 
     av[i]=""; // initialise each const char* 
    } 

    for(int i=0;i<5;i++){ 
     sav[i] = intToString(i); // Keep the original in sav[] 
     av[i] = sav[i].c_str(); // point to each string's contents 
     for(int j=0;j<5;j++){ std::cout << j << " : " << av[j] << std::endl;} 
    } 

} 

@Philip: Notez que vos impressions de programme chaque av[] après chaque av[] est réinitialisée.

Notez que la gestion de la mémoire est gérée par sav[]

Questions connexes