malloc() - C++ - Programmation
Marsh Posté le 01-04-2003 à 15:45:28
Peak a écrit : quelqu'un saurait-il m'expliquer comment ceci peut fair cela : |
segmentation
Marsh Posté le 01-04-2003 à 15:46:27
Citation : coup de bol |
Disont que theoriquement il est sensé y'avoir un expliquation logique!?
Marsh Posté le 01-04-2003 à 15:48:11
ce serait pas du à une optimisation du compilo sur un prog simple ?
Bon ... Ce serait vraiment hasardeux, mais bon ...
tu as fait plusieurs tests ? Parce que ca ressemble à un gros cas particulier quand même ...
Marsh Posté le 01-04-2003 à 15:54:55
dans le cas du char* S, S pointe n'importe où (car il est pris sur la pile qui contiens des valeurs aléatoires).
si hors de l'espace virtuel => seg fault.
dans le cas de char* S=malloc(0), à priori un NULL est retourné.
forcément dans l'espace virtuel => écrasement du début du segment de donnée...
je vois ça comme ça....
Marsh Posté le 01-04-2003 à 15:56:54
NULL ne fait pas partie de l'espace d'adressage (au moins sous win), les access violation sur l'adresse 0x0 j'en ai vu un paquet
Marsh Posté le 01-04-2003 à 15:58:24
C'est sur que le compilo te jette dès que tu fais un accès à l'adresse 0 !
Marsh Posté le 01-04-2003 à 16:00:40
sinon jeu interressant (pas essayé perso) :
penser à désactiver les optimisations, notemment l'inline automatique:
Code :
|
Marsh Posté le 01-04-2003 à 16:01:07
chrisbk a écrit : NULL ne fait pas partie de l'espace d'adressage (au moins sous win), les access violation sur l'adresse 0x0 j'en ai vu un paquet |
bin temps pi alors
Marsh Posté le 01-04-2003 à 16:03:45
[citation=349285,1]
char *S=machin; // faudrait être sûr que l'offset soit [/citation]
il doit te manquer un gros cast des familles !
mais ca peut être fun !
Marsh Posté le 01-04-2003 à 16:05:51
theShOcKwAvE a écrit : ce serait pas du à une optimisation du compilo sur un prog simple ? |
apparement ça marche pour une string de n'importe quel taille et si je fait :
Code :
|
j'ai 3blocs aloué et je met 8 (ou même 20)char ça marche toujours??
Marsh Posté le 01-04-2003 à 16:08:21
wé mais comme les OS fonctionnent par pages de 4Ko ou 4Mo en x86, le seg fault ne peut se déclencher que par rapport à cette granularité....
de plus je sais aps si les malloc ont une granularité....
Marsh Posté le 01-04-2003 à 16:14:07
Ca me dérange quand même qu'il ne te jette pas dès que tu fais le sprintf .... Un accès en écriture n'importe où, t'as peu de chances que ca passe .... Encore moins de chance que de réussir une lecture au même endroit, d'ailleurs !
Marsh Posté le 01-04-2003 à 16:39:50
je vous avoue que j'aurai aussi préferé me fair jetter dès que je fais le sprintf (c'étai d'ailleur mon but quand j'ai testé)
Au moins j'aurai eu l'imprétion de comprendre quelque chose
Marsh Posté le 03-04-2003 à 09:15:13
Il suffit de savoir comment fonctionne malloc pour comprendre :-)
En fait, chaque processus possede un espace d'adresse virtuel. Cet espace est separe en 3 parties : pile, text et data. C'est dans cette derniere partie que sera stockees tous nos donnes dynamiques. Pour definir la taille de cette zone, il faut deplacer un "break" (man sbrk).
Si l'on demande 12 octets, malloc va deplacer le break de bien plus pour d'une part stocker ses propres informations (taille du bloc allouee), et d'autre part pour "bufferiser" les appels a sbrk (appel systeme couteux en temps).
Or pour faire un segfault, il fait etre en dehors du data (avant le edata ou derriere le brk)...
Voila qui explique certaines chose
Marsh Posté le 03-04-2003 à 09:18:21
Tu ne serais pas en mode debug par hasard ?
Il me semble que j'avais lu que dans ce mode, certain compilo (Visual pour ne pas le citer) allouait un peu plus que demandé pour éviter les dépassement de tableau.
Marsh Posté le 03-04-2003 à 10:50:46
pascal_ a écrit : Tu ne serais pas en mode debug par hasard ? |
debug ou pas, malloc alloue toujours plus que ce que tu lui demandes. Tu n'as pas lu mon post a ce sujet ?
Marsh Posté le 03-04-2003 à 11:20:55
Kyser a écrit : |
Un petit tour sur msdn :
[link]
http://msdn.microsoft.com/library/ [...] g_Heap.asp
[/link]
On trouve :
"For example, suppose your application contains the call: malloc( 10 ).
In a Release build, malloc would call the base heap allocation routine requesting an allocation of 10 bytes.
In a Debug build, however, malloc would call _malloc_dbg, which would then call the base heap allocation routine requesting an allocation of 10 bytes plus approximately 36 bytes of additional memory."
Donc, voila : en debug visual alloue plus que tu lui demande (environ 36 bytes pour les opérations de debug).
Et TOC !
Marsh Posté le 03-04-2003 à 11:48:59
oui mais le monsieur te décrit comment ça se passe au niveau os sur sous unix/linux.
à priori windows devrait +ou- faire la même chose (granularité sur le segment de donnée)
Marsh Posté le 03-04-2003 à 13:25:12
BJOne a écrit : oui mais le monsieur te décrit comment ça se passe au niveau os sur sous unix/linux. |
Je suis d'accord avec le monsieur pour la granularité.
Cependant si le type avec visual en mode debug fait
Code :
|
visual alloue n'ont pas un block de 0 mais un block de 36.
Donc si le prog ne plante pas ce n'est pas à cause de la granularité (par contre, en mode release, si).
Marsh Posté le 04-04-2003 à 01:29:25
pascal_ a écrit :
|
Tu n'as pas bien compris, et mon message, et MSDN.
"In a Release build, malloc would call the base heap allocation routine requesting an allocation of 10 bytes."
Or, la "base heap allocation routine", alloue FORCEMENT plus que les octets que tu lui demandes, pour stocker des informations indispensable a malloc. Ne serait-ce que la taille du bloc (utilise pour les appels a FREE).
Sinon comment que tu crois que malloc retrouve ts les pointeurs alloue ?
De plus l'alignement des donnes fait que tu auras tjs plus d'octets que demande (mais c'est transparant et il ne faut pas se baser dessus). Exemple avec 10, tu devrais tomber sur 12 ou 16 octets.
En fait je parlais plus de l'exemple
Code :
|
qui ne segfault pas.
Pour l'exemple avec malloc(0), sous unix cela amenerait directement a un segfault, et visiblement sous Windows non ... peut-etre a cause du debug effectivement.
Marsh Posté le 04-04-2003 à 01:31:32
Petite precision sur l'explication de malloc pour ceux que ca interesse :
Pour les grosses allocations, malloc fait plutot appel a mmap que sbrk, ce dernier etant beaucoup plus couteux en terme de performances.
Voila
Marsh Posté le 04-04-2003 à 08:38:22
Citation : Pour l'exemple avec malloc(0), sous unix cela amenerait directement a un segfault, et visiblement sous Windows non ... peut-etre a cause du debug effectivement. |
par contre y'a gros risque d'assert au moment du free...
Perso g jamais compris l'interet de cette histoire de debug, je prefere avoir une grosse exception au moment precis ou j'ecris n'imo en ram plutot qu'un assert en fin de prog pour dire que plus tot j'ai fin n'imp....
edit : ou c'est justement parce que on alloue la memoire que par block ....
Marsh Posté le 07-04-2003 à 22:39:10
C'est pas du clustering mémoire ?
ou alors si cet espace n'est pas réservé par une autre applic/fct, il te jette pas.
par exemple
Code :
|
A mon avis, il te laisse écrire (pas longtemps mais quand même)
Marsh Posté le 01-04-2003 à 15:37:05
quelqu'un saurait-il m'expliquer comment ceci peut fair cela :
-> y me m'affiche "1234567" suivit d'un "segmentation fault"
jusqu'ici tout est logique (j'ai pas alloué de bloc a S)
-> mais maintenant ça marche pourtant j'ai alloué 0 bloc!?
pourkoi?