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 Réponses :
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 ++.)
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.
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
.
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.
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-vousmalloc
au lieu denew
en c ++?si (entrées! = NULL) a-> entrées = entrées;
- ne voulez-vous pas testerun
plutôt que (ou en plus) desentrées
? Également; n'utilisez pasmalloc
en C ++. Et préféreznullptr
à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.