2012-05-13 3 views
1
#include <iostream> 
#include <string.h> 
using namespace std; 

void newBuffer(char* outBuffer, size_t sz) { 
    outBuffer = new char[sz]; 
} 

int main(void) { 

    const char* abcd = "ABCD"; 
    char* foo; 
    foo = NULL; 
    size_t len = strlen(abcd); 
    cout<<"Checkpoint 1"<<endl; 
    newBuffer(foo, len); 
    cout<<"Checkpoint 2"<<endl; 

    cout<<"Checkpoint 2-A"<<endl; 
    memset(foo, '-', len); 
    cout<<"Checkpoint 3"<<endl; 
    strncpy(foo, abcd, len); 
    cout<<"Checkpoint 4"<<endl; 
    cout << foo << endl; 

    int hold; 
    cin>>hold; 
    return 0; 

}Accédez à l'emplacement d'écriture de violation 0x00000000. fonction memset émet

Ce programme se bloque entre checkpoint 2-1 et 3. Ce qu'il essaie de faire est de définir le tableau de caractères foo au caractère « - », mais il échoue à cause d'un accès problèmes. Je ne comprends pas pourquoi cela arrive. Merci beaucoup d'avance!

+0

À moins que ce soit une question de jouet/éducation: Un autre excellent exemple pourquoi vous devriez utiliser 'std :: string' ou' std :: vecteur' pour des choses comme ça en C++! –

Répondre

6

Votre fonction newBuffer doit accepter le premier paramètre par référence afin que les modifications apportées à l'intérieur de la fonction sont visibles à l'appelant:

void newBuffer(char*& outBuffer, size_t sz) { 
    outBuffer = new char[sz]; 
} 

Comme il est maintenant, vous assignez le résultat de new char[sz] à la section locale variable outBuffer qui est seulement une copie de la variable foo de l'appelant, donc quand la fonction retourne c'est comme si rien ne s'est jamais produit (sauf que vous avez fui la mémoire).

Vous avez également un problème en ce que vous allouez le tampon à la taille de la longueur de ABCD qui est 4. Cela signifie que vous pouvez contenir jusqu'à 3 caractères dans ce tampon car un est réservé à la terminaison NUL à la fin. Vous devez ajouter + 1 à la longueur quelque part (je le ferais dans l'appel à la fonction, pas à l'intérieur, car newBuffer ne devrait pas être spécialisé pour C-cordes). strncpy seulement NUL-termine le tampon si la chaîne source est assez courte, donc dans ce cas, vous êtes seulement chanceux qu'il se trouve 0 en mémoire après votre tampon alloué.

N'oubliez pas non plus delete[] foo dans main une fois que vous avez terminé (même si cela n'a pas vraiment d'importance pour un programme de cette taille).

+0

Dang! C'était trivial. Je n'ai pas remarqué ça. Merci beaucoup. – FrozenLand

2

Il échoue car votre fonction newBuffer ne fonctionne pas réellement. Le moyen le plus simple de résoudre ce problème serait de changer la déclaration en void newBuffer (char *&outBuffer, size_t sz). Comme il est écrit, l'adresse de la mémoire nouvellement allouée n'est pas réellement stockée dans le foo du principal parce que le pointeur est passé par la valeur.

0

Vous passez le pointeur par valeur. Vous devez passer soit une référence au pointeur, soit l'adresse du pointeur.

Cela dit, en utilisant la valeur de retour serait mieux à mon avis:

char* newBuffer(size_t sz) { 
    return new char[sz]; 
} 

Quand écrit de cette façon, la fonction newBuffer ne semble pas vraiment la peine. Vous n'en avez pas besoin. Vous pouvez utiliser new directement et ce serait plus clair.

Bien sûr, si vous utilisez C++, tout cela est inutile. Vous devriez utiliser string, pointeurs intelligents, etc. Vous ne devriez pas avoir besoin d'appeler new directement. Une fois que vous corrigez le bogue dont vous parlez dans cette question, vous rencontrerez le problème que votre chaîne n'est pas terminée par des zéros et que le tampon est trop court pour contenir la chaîne car vous avez oublié d'allouer de l'espace pour la terminaison nulle. Une des bonnes choses à propos de C++ est que vous pouvez échapper aux horreurs de la manipulation de chaînes en C.

Questions connexes