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
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
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
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
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
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 :
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
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
xavier <xtrochu@yahoo.com> 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
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
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
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.
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
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
xavier <xtrochu@yahoo.com> 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
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
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
Jean-Marc Bourguet a dit le 10/02/2005 16:17:
xavier <xtrochu@yahoo.com> 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'
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
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 in-th elements of the array object, provided they exist.
Aucune allusion n'est faite à une conversion signé vers non-signé.
Falk
Jean-Marc Bourguet wrote:
xavier <xtrochu@yahoo.com> 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 in-th elements of the array
object, provided they exist.
Aucune allusion n'est faite à une conversion signé vers non-signé.
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 in-th elements of the array object, provided they exist.
Aucune allusion n'est faite à une conversion signé vers non-signé.
Falk
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
xavier wrote:
Jean-Marc Bourguet a dit le 10/02/2005 16:17:
xavier <xtrochu@yahoo.com> 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...
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
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
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.
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.