Voici le prototype de ma variable:
QFile* currentFile;
et voici, la définition de la variable
currentFile = new QFile();
j'ai pas d'érreur de segmentation, mais j'aimerais savoir pourquoi quand je remplace la définition par ça, j'ai une érreur de segmentation quand j'utilise ma variable:
QFile* currentFile = new QFile();
besoin de voir plus de code.
mais de facon generql, => valgrind.
bool Exotic::setCurrentFile(const QString &filePath)
{
if (currentFile->fileName().isEmpty())
{
currentFile->close();
}
currentFile->setFileName(filePath);
currentFile->open(QIODevice::ReadWrite);
ui->editor->setPlainText(QString(currentFile->readAll()));
return 0;
}
Voici la fonction qui utilise currentFile
Il faut un code complet pour pouvoir diagnostiquer un probleme comme ca.
Mes deux fichiers:
Exotic.h: http://pastebin.com/BNpeGkeS
Exotic.cpp: http://pastebin.com/73GYpk9Y
lorsque tu as des erreurs de segmentation, comme dit godrik, compile avec le flag de debug -g
et ensuite lance valgrind ça te dira à quelle ligne tu fais une tentative d'accès illégale
sinon pour revenir à ton sujet initial, quand tu fais ça:
QFile* currentFile;
currentFile = new QFile();
tu déclares un nouveau pointeur currentFile (en plus de l'attribut currentFile de ton instance courante, mais il s'agit bien de deux variables différentes malgré le nom commun)
donc tu as currentFile, le pointeur que tu viens de crée (ce pointeur currentFile sera détruit une fois que tu seras sorti du bloc courant)
et this->currentFile le currentFile de l'instance courante
ensuite tu alloues dynamiquement un QFile dont l'adresse est affecté dans ton attribut currentFile (donc this->currentFile et non dans le pointeur currentFile que tu as déclaré précédemment)
donc, currentFile est nullptr et this->currentFile est bien alloué, donc il n'y aura pas segfault par la suite
par contre, dans le deuxieme cas
QFile* currentFile = new QFile();
ici this->currentFile sera nullptr, car tu alloues dans une nouveau pointeur qui ne sera plus accessible quand tu sortiras du bloc courant, donc ici tu auras une fuite mémoire en plus d'un segfault
Le 02 mars 2015 à 18:50:32 [DenshaOtoko] a écrit :
lorsque tu as des erreurs de segmentation, comme dit godrik, compile avec le flag de debug-g
et ensuite lance valgrind ça te dira à quelle ligne tu fais une tentative d'accès illégalesinon pour revenir à ton sujet initial, quand tu fais ça:
QFile* currentFile; currentFile = new QFile();
tu déclares un nouveau pointeur currentFile (en plus de l'attribut currentFile de ton instance courante, mais il s'agit bien de deux variables différentes malgré le nom commun)
donc tu as currentFile, le pointeur que tu viens de crée (ce pointeur currentFile sera détruit une fois que tu seras sorti du bloc courant)
et this->currentFile le currentFile de l'instance couranteensuite tu alloues dynamiquement un QFile dont l'adresse est affecté dans ton attribut currentFile (donc this->currentFile et non dans le pointeur currentFile que tu as déclaré précédemment)
donc, currentFile est nullptr et this->currentFile est bien alloué, donc il n'y aura pas segfault par la suite
par contre, dans le deuxieme cas
QFile* currentFile = new QFile();
ici this->currentFile sera nullptr, car tu alloues dans une nouveau pointeur qui ne sera plus accessible quand tu sortiras du bloc courant, donc ici tu auras une fuite mémoire en plus d'un segfault
QFile* currentFile;
Alors c'est inutile de déclarer currentFile, vu que j'utilise this->currentFile et pas l'autre
Dans le deuxième cas, pourquoi this->currentFile serait inaccessible à la sortie du bloc courant ? j'ai pourtant faire une allocation dynamique alors ça devrait pas être limité par la porté du bloc, mais ça devrait attendre que j'utilise l'opérateur delete, non
C'est pour ca que je voulais voir tout le code
Si tu utilise QFile* currentFile = new QFile(); dans le constructeur, alors tu as deux variable currentFile, une dans la structure et une dans la pile d'appel. C'est la variable de la pile d'appel que tu changes et pas la variable qui est dans la structure.
La memoire alloue dynamiquement est toujours disponible, mais tu n'as plus de pointeur dessus, donc elle est inaccessible.
Et pourquoi quand je fais QFile* currentFile = new QFile();
il n'y aurait pas une érreur qui dit que je déclare une une variable déjà déclaré ? vu que ça a déjà été déclaré dans exotic.h
C'est quoi la structure ?
non ce n'est pas une erreur par ce que la variable est scope differement. Ce le meme phenomene qui te permet d'avoir une variable globale et local qui ont le meme nom. La variable la plus "proche" est celle qui est reference. Tu peux toujours acceder a celle de la structure avec this->currentFile. Cela etant dit certains compilateur mettent un message d'avertissement quand une variable en cache une autre.
Et la structure c'est "Exotic" ici. (mmm, c'est une classe, mais bon c'est pas bien different en C++.)
Faut se méfier des noms. Tu peux aussi retrouver ce cas de figure, si t'es tête en l'air ou que t'utilises une librairie quelconque :
// currentFile réfère à la variable déclarée dans la classe
void Exotic::setQFile(QFile argFile)
{
currentFile = argFile;
}
// currentFile réfère à l'argument (variable locale)
// this->currentFile réfère à la variable déclarée dans la classe
void Exotic::setQFile(QFile currentFile)
{
this->currentFile = currentFile;
}
Ca y est j'ai compris, merci Godrik, et [DenshaOtoko]