1
votes

Avertissement 6011 en C ++

Je ne comprends pas la signification de cet avertissement. Mon code se compile mais ne parvient pas à lire entrées la moitié du temps.

A* createA(double* inputs) 
{
    A* a = (A*)malloc(sizeof(A));
    if (inputs != NULL)
        a->inputs = inputs;
    else /* error */
}

Je crée une nouvelle structure A:

A* createA(double* inputs) 
{
    A* a = (A*)malloc(sizeof(A));
    a->inputs = inputs;
}

Pourquoi est-ce que j'obtiens l'avertissement 6011 sur a-> inputs = inputs; ?

Dans la documentation Microsoft, il est dit de tester si le l'argument donné est NULL avant d'alimenter a-> entrées , ce qui est en effet une bonne pratique pour suivre les erreurs.

Mais même en ajoutant:

typedef struct a
{
    double* inputs;
} A;

Je reçois toujours l'avertissement mais sur l'instruction if .


3 commentaires

Je crois que l'avertissement fait référence à la variable a , pas à inputs , c'est-à-dire. vous ne gérez pas le cas lorsque l'allocation échoue. Mais pourquoi utilisez-vous malloc au lieu de new en c ++?


si (entrées! = NULL) a-> entrées = entrées; - ne voulez-vous pas tester un plutôt que (ou en plus) des entrées ? Également; n'utilisez pas malloc en C ++. Et préférez nullptr à NULL .


@clcto Je suis un débutant en C ++, j'ai surtout appris C. Vieille habitude. Je devrais aussi créer une classe pour A. Et vous avez raison sur a . Merci.


3 Réponses :


-3
votes

Il y a un problème de mémoire dans votre cas, car dans la structure a, il y a les entrées du pointeur.

les entrées ne sont pas attribuées. Vous devez allouer de la mémoire pour faire pointer les entrées OU vous devez lui affecter NULL, dans un constructeur par exemple (oui, vous pouvez ajouter un constructeur à une structure en C ++.)


3 commentaires

Je nourris createA avec un double * alloué. Le problème ne consistait pas à vérifier si a était NULL lors de sa création.


il se peut qu'il y ait une confusion entre deux entrées différentes: l'une à l'intérieur de la classe et l'autre comme argument de fonction. Pourriez-vous essayer d'en changer un?


Merci d'avoir contribué! J'ai du mal à comprendre votre réponse. Ce n'est pas un problème sur ce que pointe le membre input , mais plutôt sur le déréférencement de a après l'avoir alloué. Notez également que les constructeurs ne seront pas appelés par malloc , donc cette réponse est un peu incomplète.



1
votes

Comme @clcto l'a expliqué, c'est parce que vous ne faites pas de vérification d'erreur.

Si vous ne vous souciez pas du MOO et que vous pouvez utiliser des exceptions, faites simplement:

struct A
{
    double* inputs;
};

A* createA(double* inputs) 
{
    A* a = new A;
    a->inputs = inputs;
    return a;
}

Parce que new lancera sur MOO. Si vous ne pouvez pas utiliser d'exceptions et / ou souhaitez vérifier la valeur de retour à la place, regardez en utilisant new(std::nothrow).

Notez également la notation sur struct Un , au lieu d'un typedef (inutile en C ++). De plus, vous devriez probablement envisager d'utiliser à la place std :: unique_ptr .


0 commentaires

1
votes

Le problème est que malloc peut renvoyer NULL en cas d'échec. Dans ce cas, écrire dans a-> inputs dans la ligne suivante serait déréférencer le pointeur NULL , qui est un comportement indéfini, et devrait être évité. Il est certes peu probable que malloc échoue, mais comme vous aimez écrire du code sécurisé, vous devriez tester la valeur de retour de malloc :

// no typedef
struct A {
    vector<double> inputs;
};

// no createA

// Example usage:
int main(){
    A a;

    // no manual memory management!!!

    // no pointers!

    // how many inputs?
    cout << "There are " << a.inputs.size() << " inputs\n";

    // add two inputs
    a.inputs.push_back(3.83);
    a.inputs.push_back(1.01);

    // print everything
    for (const auto& input : a.inputs){
        cout << input << " ";
    }

    return 0;
}

Puisque vous écrivez du C ++ à partir d'un arrière-plan C, vous devez être conscient que le code que vous écrivez est essentiellement encore C, et est très différent du C ++ moderne, dans lequel nous faisons beaucoup de choses très différemment . En C ++, il existe de nombreux outils et idiomes très utiles que nous aimons utiliser.

Je suppose que inputs est une liste de nombres. En C ++, je réécrirais votre code comme suit:

A* a = (A*)malloc(sizeof(A));
if (a != NULL){
    a->inputs = inputs;
} else {
    /* Handle error */
}

C'est ainsi que nous faisons habituellement les choses en C ++ de nos jours. Il se passe beaucoup de choses sous le capot, mais l'expérience globale est très sûre et conviviale une fois que vous savez ce que vous faites. Si vous êtes intéressé, je vous suggère de faire votre choix parmi cette liste de bons livres C ++ et lisez attentivement. Sinon, il serait peut-être plus simple de s'en tenir à C, si c'est ce avec quoi vous êtes à l'aise.


0 commentaires