 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
fabrizio Guest
|
Posted: Thu Feb 10, 2005 11:01 am Post subject: que faire quand new plante? |
|
|
Bonjour,
je cherche des pistes pour comprendre pourquoi mon programme
me sort un segmentation fault.
les symptomes sont les suivants :
dans une fonction j'ai un truc comme ça :
dummyclasse* ptr = new dummyclasse(1,2);
qui, apparemment, provoque un segmentation fault.
j'ai remplacé ceci par :
dummyclasse* ptr = (dummyclasse*)malloc(sizeof(dummyclasse));
ce qui me provoque le même segfault
en revanche :
dummyclasse a(1,2);
ne pose pas de problème
auriez vous quelque idée ?
Fabrice
|
|
| Back to top |
|
 |
xavier Guest
|
Posted: Thu Feb 10, 2005 11:23 am Post subject: Re: que faire quand new plante? |
|
|
fabrizio a dit le 10/02/2005 12:01:
| Quote: | auriez vous quelque idée ?
|
A priori, je dirais que la mémoire est déjà corrompue avant l'appel à
malloc ou new.
Regarde du coté des écritures sur des objets alloués dynamiquement
précédent l'appel.
Si le code unique :
! class dummyclasse { /* ... */ };
!
! int main() {
! dummyclasse * p = new dummyclasse (1, 2);
! delete p;
! }
plante, une étude du code du constructeur est nécéssaire pour déterminer
le problème.
xavier
|
|
| Back to top |
|
 |
fabrizio Guest
|
Posted: Thu Feb 10, 2005 11:26 am Post subject: Re: que faire quand new plante? |
|
|
| Quote: | A priori, je dirais que la mémoire est déjà corrompue avant l'appel à
malloc ou new.
|
ca veut dire quoi que la mémoire est "corrompue" ?
ca peut venir de quoi ?
| Quote: | Regarde du coté des écritures sur des objets alloués dynamiquement
précédent l'appel.
Si le code unique :
! class dummyclasse { /* ... */ };
!
! int main() {
! dummyclasse * p = new dummyclasse (1, 2);
! delete p;
! }
plante, une étude du code du constructeur est nécéssaire pour déterminer
le problème.
|
ah oui j'avais oublié. ceci fonctionne.
donc je pense que le problème n'est pas dans le constructeur.
ceci étant corroboré par la fait que un simple malloc provoque le même
segfault.
merci pour ta réponse
|
|
| Back to top |
|
 |
flure Guest
|
Posted: Thu Feb 10, 2005 11:53 am Post subject: Re: que faire quand new plante? |
|
|
fabrizio a écrit :
| Quote: | A priori, je dirais que la mémoire est déjà corrompue avant l'appel à
malloc ou new.
ca veut dire quoi que la mémoire est "corrompue" ?
ca peut venir de quoi ?
|
Ça veut dire que tu as une fuite mémoire, ou un débordement quelque part
avant ton new. Utilise un outil comme Valgrind pour le repérer ...
Si tu es sur un système Linux, tu as Alleyoop qui est un front-end à
Valgrind, très pratique à utiliser.
Personnellement j'utilise régulièrement ce genre d'outils pour corriger
les erreurs (en général d'inattention) dans mes allocations/déallocations.
--
Florent "flure" C.
http://flure.free.fr
|
|
| Back to top |
|
 |
xavier Guest
|
Posted: Thu Feb 10, 2005 12:18 pm Post subject: Re: que faire quand new plante? |
|
|
fabrizio a dit le 10/02/2005 12:26:
| Quote: | ca veut dire quoi que la mémoire est "corrompue" ?
|
Pour pouvoir fonctionner correctement malloc maintient une structure de
donnée, invisible pour l'utilisateur, qui lui indique quelle zone de la
mémoire est disponible ou indisponible.
Une action dans ton programme a écrit une donnée dans cette structure.
Elle est donc corrompue et entraîne le plantage de malloc.
| Quote: | ca peut venir de quoi ?
|
La plupart du temps, il s'agit d'une écriture hors limite. Par exemple :
! char * p = malloc(10);
! p[-1] = 0; // écriture avant la zone, grand risque de corruption
! p[10] = 0; // écriture après la zone, idem.
Pour abonder dans le sens de flure, il existe tout un tas de
bibliothèque et outils qui te permettent de vérifier de manière
automatique ce genre d'erreur. Valgrind en est un particulièrement bien
fichu.
xavier
|
|
| Back to top |
|
 |
flure Guest
|
Posted: Thu Feb 10, 2005 12:31 pm Post subject: Re: que faire quand new plante? |
|
|
xavier a écrit :
| Quote: | ! p[-1] = 0; // écriture avant la zone, grand risque de corruption
|
C'est possible, ça ???
Je pensais qu'un index de tableau était obligatoirement unsigned int ?
C'est une question, pas une critique, bien sûr :)
--
Florent "flure" C.
http://flure.free.fr
|
|
| Back to top |
|
 |
xavier Guest
|
Posted: Thu Feb 10, 2005 1:27 pm Post subject: Re: que faire quand new plante? |
|
|
flure a dit le 10/02/2005 13:31:
| Quote: | xavier a écrit :
! p[-1] = 0; // écriture avant la zone, grand risque de corruption
C'est possible, ça ???
|
Oui.
exemple :
! #include <iostream>
! #include <iterator>
! #include <algorithm>
!
! int main() {
! char buffer[3] = {1, 2, 3};
! char * p = buffer + 2;
! p[-1] = 4;
! std::copy(buffer, buffer + 3,
! std::ostream_iterator<int>(std::cout, " "));
! std::cout << std::endl;
! }
| Quote: | Je pensais qu'un index de tableau était obligatoirement unsigned int ?
|
Ben non.
! $ g++ -ansi -Wall -Werror -pedantic -o test_array test_array.cpp
! $ test_array
! 1 4 3
! $
xavier
|
|
| Back to top |
|
 |
fabrizio Guest
|
Posted: Thu Feb 10, 2005 1:41 pm Post subject: Re: que faire quand new plante? |
|
|
merci à xavier et flure pour vos réponses.
|
|
| Back to top |
|
 |
nmartin Guest
|
Posted: Thu Feb 10, 2005 1:58 pm Post subject: Re: que faire quand new plante? |
|
|
| Quote: | Je pensais qu'un index de tableau était obligatoirement unsigned int ?
Ben non.
! $ g++ -ansi -Wall -Werror -pedantic -o test_array test_array.cpp
! $ test_array
! 1 4 3
! $
xavier
|
j'ai aussi vu qu'avec gcc ce code compilait :
int main(...){
int N;
cin >> N;
char buffer[N];
....
}
nico
|
|
| Back to top |
|
 |
Alexandre Guest
|
Posted: Thu Feb 10, 2005 2:13 pm Post subject: Re: que faire quand new plante? |
|
|
"flure" <hamiral (AT) hamham (DOT) fr> a écrit dans le message de news:
420b5494$0$5212$7a628cd7 (AT) news (DOT) club-internet.fr...
| Quote: | xavier a écrit :
! p[-1] = 0; // écriture avant la zone, grand risque de corruption
C'est possible, ça ???
Je pensais qu'un index de tableau était obligatoirement unsigned int ?
non, un entier étant par défaut signé, il est logique que [] attende un int. |
(donc signed int).
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
|
| Back to top |
|
 |
xavier Guest
|
Posted: Thu Feb 10, 2005 2:19 pm Post subject: Re: que faire quand new plante? |
|
|
nmartin a dit le 10/02/2005 14:58:
| Quote: | j'ai aussi vu qu'avec gcc ce code compilait :
int main(...){
int N;
cin >> N;
char buffer[N];
...
}
|
Dans ce cas, il s'agit d'une extension spécifique et documentée de g++.
! #include <iostream>
!
! int test() {
! int n;
! std::cin >> n;
! char buffer[n];
!
! return buffer[0];
! }
compilation 'normale', avec l'extension activée :
! $ g++ -Wall -Werror -c -o test_array test_array.cpp && echo succeeded
! succeeded
compilation 'stricte', sans l'extension :
! $ g++ -pedantic -c -o test_array test_array.cpp && echo succeeded
! test_array.cpp: In function `int test()':
! test_array.cpp:6: error: ISO C++ forbids variable-size array `buffer'
Pour revenir à ta remarque, tu peux vérifier que Comeau, en mode strict,
compile sans voir d'erreurs l'exemple que j'ai donné précédemment.
xavier
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Thu Feb 10, 2005 2:21 pm Post subject: Re: que faire quand new plante? |
|
|
xavier <xtrochu (AT) yahoo (DOT) com> writes:
| Quote: | ! $ g++ -ansi -Wall -Werror -pedantic -o test_array test_array.cpp
! $ test_array
! 1 4 3
! $
|
Ca prouve quoi? Si le -1 etait converti implicitement en unsigned, le
comportement serait a priori le meme (et sans conversion implicite,
p[1] serait une erreur). Pour voir une difference, il faudrait par
exemple executer le prog avec des int de 32 bits sur un systeme ou
l'espace virtuel est de 64 bits.
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
|
|
| Back to top |
|
 |
xavier Guest
|
Posted: Thu Feb 10, 2005 2:32 pm Post subject: Re: que faire quand new plante? |
|
|
Jean-Marc Bourguet a dit le 10/02/2005 15:21:
| Quote: | Ca prouve quoi? Si le -1 etait converti implicitement en unsigned, le
comportement serait a priori le meme (et sans conversion implicite,
p[1] serait une erreur). Pour voir une difference, il faudrait par
exemple executer le prog avec des int de 32 bits sur un systeme ou
l'espace virtuel est de 64 bits.
|
C'est juste, même si rien dans ce que j'ai écrit permet de déterminer
sur quelle architecture le test est fait. Encore que la conversion
implicite en valeur unsigned de même taille que le pointeur implique une
saturation lors de l'opération. Le comportement dans ce cas est-il défini ?
Une autre façon, je pense de comprendre que cela est possible est de
comparer :
! p[-1] = 0;
et
! *(p - 1) = 0;
xavier
|
|
| Back to top |
|
 |
Jean-Marc Bourguet Guest
|
Posted: Thu Feb 10, 2005 2:33 pm Post subject: Re: que faire quand new plante? |
|
|
xavier <xtrochu (AT) yahoo (DOT) com> writes:
| Quote: | Jean-Marc Bourguet a dit le 10/02/2005 15:21:
Ca prouve quoi? Si le -1 etait converti implicitement en unsigned, le
comportement serait a priori le meme (et sans conversion implicite,
p[1] serait une erreur). Pour voir une difference, il faudrait par
exemple executer le prog avec des int de 32 bits sur un systeme ou
l'espace virtuel est de 64 bits.
C'est juste, même si rien dans ce que j'ai écrit permet de
déterminer sur quelle architecture le test est fait.
|
L'absence d'option pour gcc. Ce doit etre assez rare de l'installer
de sorte qu'il compile en 64 bits sans -march.
| Quote: | Encore que la conversion implicite en valeur unsigned de même taille
que le pointeur implique une saturation lors de l'opération. Le
comportement dans ce cas est-il défini ?
|
Non. C'est pour cela que j'ai ecrit "a priori".
A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|