11
votes

C ++ affectation de la mémoire dynamique dans une fonction - Question de Newbie

Je cherche une fuite de mémoire et de ce que je vois, le problème ressemble à ceci: xxx

au point // Commentaire du code, je m'attendais à ce que CP pointe sur la mémoire allouée, Mais c'est toujours un pointeur nul signifiant que je ne supprimais jamais la mémoire. Qu'est-ce que je fais wroing?


3 commentaires

Je suppose que cbuf était supposé être cp ?


Que diriez-vous de poser du code réel. À moins que le code ne soit coupé et coller, il y a la possibilité d'ajouter des erreurs. Cela rend juste Thigs plus fort et nous finissons par résoudre des erreurs coupées et coller comme CBUF -> CP


Désolé pour ça, je vais garder cela à l'esprit la prochaine fois. Oui cbuf était censé être cp


7 Réponses :


6
votes

Le paramètre CP est une variable locale de la fonction - changeant qu'elle ne modifie rien en dehors de la fonction. Un meilleur moyen d'écrire la fonction est la suivante:

char * func(){
    return new char[100];
}


4 commentaires

Hmm, deux bowvotes. Pas que je me soucie particulièrement, mais d'autres ici pourraient bénéficier de savoir ce qui ne va pas avec cette réponse.


Rien que je puisse voir. Si vous allez signaler quelque chose comme les fonctionnalités C ++ que vous avez mentionnées, je pense qu'il est probablement bon d'ajouter une partie sur la taille de la matrice. De plus, si vous allez utiliser ces fonctionnalités particulières, vous souhaitez probablement passer un pointeur sur une référence en référence pour la créer, sinon transmettre un déjà créé en référence pour éviter la pénalité du constructeur de copie ... mais Il n'y a vraiment rien de mal avec cette réponse.


Les pointeurs n'ont pas de constructeur de copie.


Je faisais référence à std :: string et std :: vecteur quand on parle de "les fonctionnalités C ++ que vous avez mentionnées". J'ai fait mangily ma réponse, désolé pour la confusion. Pour ce que vous avez, j'ajouterais "NE PAS COQUERCODE ...". Le reste fait référence aux "fonctionnalités C ++".



18
votes

Vous attribuez à cp la valeur de la mémoire allouée. Cependant, c'est une variable sur la pile: une copie du CP dans MAIN! cp est local à la fonction que vous êtes.

Ce que vous voulez est une référence: xxx

ceci sera alias cp pour être le paramètre passé.


0 commentaires

1
votes

Vous passez dans CBUF , pas cp .


2 commentaires

Même s'il passait * CP, il resterait de pointe à 0 après // code


Cela n'a pas d'importance, car vous le transmettez également par la valeur.



13
votes
void func(char *cp){
    cp = new char[100];
}
In this function, char *cp is a "pointer being passed by copy" what means that they are pointing to the same memory address but they are not the same pointer. When you change the pointer inside, making it to point to somewhere else, the original pointer that has been passed will keep pointing to 0.

0 commentaires

1
votes

La fonction change seulement une copie de cp . Utilisez une référence à la place.


0 commentaires

0
votes

GMan et Neil mentionnés, afin de travailler, vous devrez changer func à:

char * func ();

ou vide func (Char * & P);

qui résoudra votre problème immédiat.

Il y a cependant un problème de maintenance. Dans les deux cas, Func retourne un pointeur. Ce qui n'est pas clair pour l'utilisateur de Func, c'est que le pointeur retourné devra être supprimé. Pour cette raison, évitez généralement cette construction à moins que 100% nécessaire. Plutôt:

  1. Aidez l'utilisateur à affecter la bonne quantité de mémoire qui peut ensuite être transmise à Func
  2. Utilisez un objet pour stocker la mémoire allouée. L'objet peut alors supprimer le tableau de caractères quand il est détruit.

    Donc, pour le code C ++, je recommanderais: xxx

    Cependant, dans la programmation C, en particulier, il pourrait être nécessaire de 100% d'avoir une fonction de tri pour créer le tableau. Par conséquent, dans C Programmation, vous pouvez remplacer le destructeur avec un CreateCBuf et Fonction DROITHCBUF . De cette manière, l'utilisateur de votre bibliothèque saura que le tampon retourné doit être détruit.


1 commentaires

std: le vecteur va bien. Il gère toute la gestion de la mémoire pour vous. Le problème dans l'exemple de l'OPS est que la propriété est très peu claire.



1
votes

Bien que des références sont merveilleuses dans l'offre d'une abstraction intuitive, améliorées davantage les références de rvalue C ++ 11 pour permettre la chaîne de fonction (et d'autres codages ésotériques), il est soumis à une sécurité (VIZ Pourquoi une référence est-elle considérée comme plus sûre qu'un pointeur ) Il y a des cas où il est préférable de résoudre ce qui précède avec un pointeur à l'argument de la fonction du pointeur. Spécifiquement, il est nécessaire de maintenir une base de code similaire dans ANSI C et C ++.

#include <iostream>

using namespace std;

void func(char ** cp) {
    *cp = new char[100];
    //do something useful
    (*cp)[0] = 'A';
}

void func(char *& cp) {
    cp = new char[100];
    //do something useful
    cp[0] = 'B';
}

int main(int argc, char** argv) {
    char * cp;
    //pointer to pointer
    func(&cp);
    cout << "Index 0 : " << cp[0] << '\n' << flush;
    delete[] cp; //remember to delete!!
    //pointer to ref
    func(cp);
    cout << "Index 0: " << cp[0] << '\n' << flush;
    delete[] cp;
    return 0;
}


0 commentaires