2013-02-19 4 views
0

J'apprends le C++ venant d'Objective-C/C, et pour un projet fictif je veux charger les mots du fichier /usr/share/dict/words stocké sur des machines Mac OS X. L'idée est de charger le fichier et d'obtenir chaque mot dans un tableau, alors j'ai un array de type string.C++ dynamic array of string

Mais j'ai du mal à travailler correctement avec la mémoire dynamique avec mes baies - en utilisant new et delete. J'ai ajouté une partie du code ci-dessous, si quelqu'un pouvait aider ...

Et donc je reçois une erreur de mémoire:

word:: A 
word:: a 
word:: aa 
word:: aal 
definitions(2758) malloc: *** error for object 0x100103b90: incorrect 
checksum for freed object - object was 
probably modified after being freed. 
*** set a breakpoint in malloc_error_break to debug 

mots de charge:

string* Definition::loadWords() 
{ 
    int arrayLength = 0; 

    arrayOfWords = new string[arrayLength]; 

    ifstream file; 

    file.open("/usr/share/dict/words"); 

    if(file.is_open()) 
    { 
     while(file.good()){ 
      string word; 
      getline(file, word); 
      this->addWord(word, arrayOfWords, &arrayLength); 
     } 

    } 

    file.close(); 

    cout << endl << "There are " << arrayLength << " words" << endl; 

    return arrayOfWords; 
}; 

Ajouter mots à tableau:

void Definition::addWord(string newWord, string currentArray[], int* arrayLength) 
{ 
    cout << endl << "word:: " << newWord; 

    string *placeholderArray = new string[*arrayLength + 1]; 
    placeholderArray[*arrayLength + 1] = newWord; 

    for(int i = 0; i < *arrayLength; i++){ 
     placeholderArray[i] = currentArray[i]; 
    } 

    (*arrayLength)++; 

    currentArray = placeholderArray; 

    delete [] placeholderArray; 
} 
+0

Passer à l'aide de vecteurs au lieu d'utiliser la mémoire dynamique directement. –

Répondre

1

La première chose que je peux voir est la suivante:

placeholderArray[*arrayLength + 1] = newWord; 

Vous ajoutez un élément après la fin du tableau. Les tableaux sont indexés à partir de 0. Par exemple, si la longueur du tableau est 5 alors le dernier élément du tableau est à l'index 4. Ainsi, la ligne devrait être:

placeholderArray[*arrayLength] = newWord; 

Puis, après que vous supprimez votre tableau avec ceci:

currentArray = placeholderArray; 

delete [] placeholderArray; 

Puisque vous êtes en train de définir currentArray pour pointer sur placeholderArray, puis de le supprimer.

Passer également par référence est beaucoup mieux que de passer par un pointeur.Ainsi, plutôt que ceci:

void Definition::addWord(string newWord, string currentArray[], int* arrayLength) 

Utilisez ceci:

void Definition::addWord(string newWord, string currentArray[], int& arrayLength) 

que vous n'avez pas toujours d'utiliser le * pour obtenir la valeur chaque fois que vous voulez utiliser.

Voici un tutoriel sur l'utilisation des références: http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/

vous permettent aussi d'économiser le temps et l'effort et apprendre à utiliser des vecteurs et des conteneurs stl plutôt que des tableaux plus tôt plutôt que plus tard.

Voici un tutoriel pour l'utilisation de vecteurs: http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027/C-Tutorial-A-Beginners-Guide-to-stdvector-Part-1.htm

+0

Salut, merci, vous avez tort sur votre première observation, j'utilise arrayLength + 1 qui est du tableau précédent, j'ai déjà créé un nouveau tableau avec +1 éléments, l'idée était de mettre le dernier mot avant Je copie les tableaux précédents de 0 à n - 1. Merci de m'avoir fait remarquer à propos des références par rapport aux pointeurs, j'ai raté ça. – user2085476

+0

Essayez étape dans votre programme et vous verrez ce que je dis. arrayLength commence à 0, vous ajoutez ensuite une chaîne qui passe 0 en tant que arrayLength. Vous créez un tableau de longueur arrayLength + 1 (1), puis vous ajoutez un élément à arrayLength + 1 (1), ce qui signifie que vous venez d'ajouter un élément au-delà de la fin du tableau. Donc, vous devriez créer le tableau de longueur 1 et ajouter un élément à l'index 0. –

+0

En fait, David est correct là. Par exemple, la première fois que la méthode est appelée, vous créez array [1]. Ensuite, vous définissez une valeur à array [1], qui est hors limites. –

1
currentArray = placeholderArray; 

Cette alias placeholderArray à currentArray. Ainsi, quand vous appelez ...

delete [] placeholderArray; 

.. vous êtes en train de supprimer ce à quoi pointe currentArray.

+0

Donc, ce que je devrais faire ne le supprime pas, mais alors j'ai encore un crash, je manque de mémoire – user2085476

+0

Est-ce que votre tâche nécessite que vous utilisiez des tableaux dynamiques de cette façon? Si vous pouvez utiliser des vecteurs, ce serait plus facile. –

+0

Il n'y a pas d'affectation, en fait j'essaie juste de maîtriser la mémoire dynamique, c'est pourquoi cette solution vectorielle n'est pas intéressante pour moi en ce moment. – user2085476

1

Ici vous assignez simplement le pointeur , par opposition aux valeurs du tableau:

currentArray = placeholderArray; 

Et vous libérez l'espace pointé par ledit pointeur:

delete [] placeholderArray; 

Le La prochaine fois que vous lirez de l'espace mémoire libéré entraînera un comportement indéfini.


Au lieu d'utiliser des tableaux de style C en C++, utilisez std::vector et sa fonction resize(). Mieux encore, votre application pourrait simplement invoquer push_back() sur chaque newWord, ce qui évitera tout besoin de votre addWord() fonction.