OVH Cloud OVH Cloud

que faire quand new plante?

21 réponses
Avatar
fabrizio
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

10 réponses

1 2 3
Avatar
xavier
nmartin a dit le 10/02/2005 14:58:
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

Avatar
Jean-Marc Bourguet
xavier writes:

! $ 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

Avatar
xavier
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. 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

Avatar
Jean-Marc Bourguet
xavier writes:

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.

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


Avatar
xavier
Jean-Marc Bourguet a dit le 10/02/2005 15:33:
L'absence d'option pour gcc. Ce doit etre assez rare de l'installer
de sorte qu'il compile en 64 bits sans -march.


:-)

Une chose auquel je pense, l'option -Wall active la détection des
conversions implicites signé -> non signé, donc, en théorie, si une
telle conversion avait été faite, un message d'avertissement aurait été
affiché à la compilation, et la présence de -Werror l'aurait fait échouer.

Quoi qu'il en soit, mon but dans cet exemple n'était pas d'abuser un
compilateur, mais de montrer un cas ou l'écriture de 'p[-1]' a un sens.
la seule preuve qui peut être apportée pour montrer que la construction
est valide étant de citer le standard, ce dont je ne suis pas capable.

xavier

Avatar
Jean-Marc Bourguet
xavier writes:

Jean-Marc Bourguet a dit le 10/02/2005 15:33:
L'absence d'option pour gcc. Ce doit etre assez rare de l'installer
de sorte qu'il compile en 64 bits sans -march.


:-)

Une chose auquel je pense, l'option -Wall active la détection des
conversions implicites signé -> non signé,


Tu es sur? Je ne vois rien de tel et je n'arrive pas a avoir un tel
avertissement. (Il y a bien un warning pour les comparaisons mais pas
les conversions dans d'autres contextes.).

donc, en théorie, si une telle conversion avait été faite, un
message d'avertissement aurait été affiché à la compilation, et la
présence de -Werror l'aurait fait échouer.

Quoi qu'il en soit, mon but dans cet exemple n'était pas d'abuser un
compilateur, mais de montrer un cas ou l'écriture de 'p[-1]' a un
sens. la seule preuve qui peut être apportée pour montrer que la
construction est valide étant de citer le standard, ce dont je ne
suis pas capable.


Si c'est ce qu'il faut...

5.2.1/1
[...] one of the operand shall have the type "pointer to T" and the other
shall have enumeration or integral type [...]

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


Avatar
xavier
Jean-Marc Bourguet a dit le 10/02/2005 16:17:
xavier writes:
Une chose auquel je pense, l'option -Wall active la détection des
conversions implicites signé -> non signé,


Tu es sur? Je ne vois rien de tel et je n'arrive pas a avoir un tel
avertissement. (Il y a bien un warning pour les comparaisons mais pas
les conversions dans d'autres contextes.).


Je l'étais. J'avais tord. En fait, -Wconversion, qui correspond à cette
détection, n'est pas inclue dans -Wall.

! unsigned int test() {
! return -1;
! }

$ gcc -Wconversion -c test_conv.cpp
test_conv.cpp: In function `unsigned int test()':
test_conv.cpp:2: warning: converting of negative value `-0x000000001'
to `unsigned int'

xavier


Avatar
Falk Tannhäuser
Jean-Marc Bourguet wrote:
xavier writes:
Quoi qu'il en soit, mon but dans cet exemple n'était pas d'abuser un
compilateur, mais de montrer un cas ou l'écriture de 'p[-1]' a un
sens. la seule preuve qui peut être apportée pour montrer que la
construction est valide étant de citer le standard, ce dont je ne
suis pas capable.


Si c'est ce qu'il faut...

5.2.1/1
[...] one of the operand shall have the type "pointer to T" and the o ther
shall have enumeration or integral type [...]


[...] The expression E1[E2] is identical (by definition) to *((E1)+(E2 )).
Note: see 5.3 and 5.7 for details of * and + [...]

§ 5.7/5 est intéressant afin de savoir comment l'expression *((E1)+(E 2)) est
interprétée :
[...] if the expression P points to the i-th element of an array objec t, the
expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the val ue n)
point to, respectively, the i+n-th and i–n-th elements of the array
object, provided they exist.

Aucune allusion n'est faite à une conversion signé vers non-signé.

Falk


Avatar
Loïc Joly
xavier wrote:

Jean-Marc Bourguet a dit le 10/02/2005 16:17:

xavier writes:

Une chose auquel je pense, l'option -Wall active la détection des
conversions implicites signé -> non signé,



Tu es sur? Je ne vois rien de tel et je n'arrive pas a avoir un tel
avertissement. (Il y a bien un warning pour les comparaisons mais pas
les conversions dans d'autres contextes.).



Je l'étais. J'avais tord. En fait, -Wconversion, qui correspond à cette
détection, n'est pas inclue dans -Wall.


J'aime bien ce concept de tout, mais pas vraiment...

--
Loïc



Avatar
Loïc Joly
xavier wrote:

fabrizio a dit le 10/02/2005 12:26:

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.

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.


Il existe aussi des classes de tableau qui vérifient (au moins dans
certains modes de compilation) que les arguments qu'on leur passe sont
dans l'intervalle correct.

--
Loïc


1 2 3