malloc de structure

malloc de structure - C - Programmation

Marsh Posté le 27-01-2016 à 20:35:24    

Bonjour,
ça fait longtemps que je n'ai pas fait de c, et je dois en refaire un peu.
Je vais taper le code de tête, ça n'est pas supposé compiler :)

Code :
  1. typedef struct{
  2. char* a;
  3. double b;
  4. }keyvalue;
  5. typedef struct{
  6. int nb;
  7. keyvalue* values;
  8. }dict;
  9. dict *toto = (dict*)malloc (10*sizeof(dict));


ma question est: est-ce que les values dans chaque dict sont supposées être dans un état précis? En debug sous vs2008 les pointeurs n'ont pas l'air d'etre nuls  :??: avec calloc non plus.
merci, c'est pour la science  :jap:
 
edit : en fait c'est plus que ça. Le pointeur n'a pas l'air nul, mais en plus, quand j'essaie de savoir s'il est nul, ça plante  :??:

Message cité 2 fois
Message édité par antiseptiqueincolore le 27-01-2016 à 21:10:31
Reply

Marsh Posté le 27-01-2016 à 20:35:24   

Reply

Marsh Posté le 27-01-2016 à 21:23:04    

antiseptiqueincolore a écrit :

Bonjour,
ça fait longtemps que je n'ai pas fait de c, et je dois en refaire un peu.
Je vais taper le code de tête, ça n'est pas supposé compiler :)

Code :
  1. typedef struct{
  2. char* a;
  3. double b;
  4. }keyvalue;
  5. typedef struct{
  6. int nb;
  7. keyvalue* values;
  8. }dict;
  9. dict *toto = (dict*)malloc (10*sizeof(dict));


ma question est: est-ce que les values dans chaque dict sont supposées être dans un état précis? En debug sous vs2008 les pointeurs n'ont pas l'air d'etre nuls  :??: avec calloc non plus.
merci, c'est pour la science  :jap:
 
edit : en fait c'est plus que ça. Le pointeur n'a pas l'air nul, mais en plus, quand j'essaie de savoir s'il est nul, ça plante  :??:


Malloc ne mets pas la mémoire à 0. Calloc si.
Pour le reste sans code impossible de t'aider.

Reply

Marsh Posté le 28-01-2016 à 17:14:18    

antiseptiqueincolore a écrit :

Bonjour,
ça fait longtemps que je n'ai pas fait de c, et je dois en refaire un peu.
Je vais taper le code de tête, ça n'est pas supposé compiler :)

Code :
  1. typedef struct{
  2. char* a;
  3. double b;
  4. }keyvalue;
  5. typedef struct{
  6. int nb;
  7. keyvalue* values;
  8. }dict;
  9. dict *toto = (dict*)malloc (10*sizeof(dict));


ma question est: est-ce que les values dans chaque dict sont supposées être dans un état précis? En debug sous vs2008 les pointeurs n'ont pas l'air d'etre nuls  :??: avec calloc non plus.
merci, c'est pour la science  :jap:
 
edit : en fait c'est plus que ça. Le pointeur n'a pas l'air nul, mais en plus, quand j'essaie de savoir s'il est nul, ça plante  :??:


  • en général malloc[0] alloue juste de l'espace, dans cet espace il y a n'importe quelle merde qui était dedans précédemment, ça peut être tout et n'importe quoi, souvent le contenu de mémoire précédemment désallouée
  • un pointeur null ça ne veut pas dire que sa valeur en mémoire est 0, et inversement
  • si tu deref' un pointeur avec une valeur aléatoire et que cette valeur est une page non mappée, ça se vautre, c'est normal


Sous OSX avec Clang 7.0.2, j'ai du garbage depuis le malloc et une mémoire à 0 via calloc
 

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. typedef struct {
  5.  char *a;
  6.  double b;
  7. } keyvalue;
  8. typedef struct {
  9.  int nb;
  10.  keyvalue *values;
  11. } dict;
  12.  
  13. void dump(char* v, size_t len);
  14. void dump(char* v, size_t len) {
  15.  for(size_t i = 0; i < len; ++i) {
  16.    if (i % 8 == 0) {
  17.      printf("\n" );
  18.    }
  19.    printf("%02hhx ", v[i]);
  20.  }
  21. }
  22. int main(int argc, char** argv) {
  23.  dict *toto = malloc(10*sizeof *toto);
  24.  printf("toto:\n" );
  25.  dump((char*)toto, 10*sizeof *toto);
  26.  printf("\n" );
  27.  
  28.  dict *coco = calloc(10, sizeof *coco);
  29.  printf("coco:\n" );
  30.  dump((char*)coco, 10*sizeof *coco);
  31.  printf("\n" );
  32.  
  33.  return 0;
  34. }


toto:
 
00 00 00 00 00 00 00 10  
00 00 00 00 00 00 00 10  
10 00 b0 74 ff 7f 00 00  
d4 18 2d 8b ff 7f 00 00  
c8 f0 b0 74 ff 7f 00 00  
d5 18 2d 8b ff 7f 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
coco:
 
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00  
00 00 00 00 00 00 00 00


 
[0] les bsd ont malloc.conf qui permet de configurer ça


Message édité par masklinn le 28-01-2016 à 17:32:44

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 28-01-2016 à 20:07:40    

:D  
on arrive au point que je ne comprends pas. Il me manque une bille pour comprendre.
Dans le cas d'un calloc, mon déreférencement de pointeur il plante aussi.
La zone mémoire vaut zéro on est d'accord. mais le pointeur c'est quoi son état????
avec calloc, si je fais un if(values) je passe quand même dedans.
Pour que mon code ne plante pas, il a fallu que je fasse un calloc, admettons, et que je set le pointeur à NULL par la suite pour pas que ça plante.
C'est ça que je ne comprends pas
et merci aussi

Message cité 1 fois
Message édité par antiseptiqueincolore le 28-01-2016 à 20:10:01
Reply

Marsh Posté le 28-01-2016 à 20:24:04    

antiseptiqueincolore a écrit :

:D
on arrive au point que je ne comprends pas. Il me manque une bille pour comprendre.
Dans le cas d'un calloc, mon déreférencement de pointeur il plante aussi.
La zone mémoire vaut zéro on est d'accord. mais le pointeur c'est quoi son état????


C'est un pointeur vers l'adresse 0?

antiseptiqueincolore a écrit :

avec calloc, si je fais un if(values) je passe quand même dedans.


if(values)? de quoi tu parles? Ya pas de locale values dans le peu de code que t'as donné, ça sort d'où?

antiseptiqueincolore a écrit :

C'est ça que je ne comprends pas


Que tu comprends pas quoi?


Message édité par masklinn le 28-01-2016 à 20:31:29

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 28-01-2016 à 20:31:36    

je crois que c'est la notion de NULL qui me manque. Je vais aller lire.
 
donc on a :

Code :
  1. dict *toto = (dict*)malloc (10*sizeof(dict));


 et je me fais un truc après du style if (toto[0].values) blabla. Et c'est là que je suis étonné de passer dedans.
Je m'attendais à ce que des double soient mis à zéro et les pointeurs à null.
et donc c'est pas le cas.

Message cité 1 fois
Message édité par antiseptiqueincolore le 28-01-2016 à 20:32:02
Reply

Marsh Posté le 28-01-2016 à 22:46:08    

antiseptiqueincolore a écrit :

je crois que c'est la notion de NULL qui me manque. Je vais aller lire.

 

donc on a :

Code :
  1. dict *toto = (dict*)malloc (10*sizeof(dict));


 et je me fais un truc après du style if (toto[0].values) blabla. Et c'est là que je suis étonné de passer dedans.
Je m'attendais à ce que des double soient mis à zéro et les pointeurs à null.
et donc c'est pas le cas.


1. comme il te l'a été dit, un malloc ne fait pas d'initialisation il réserve juste l'espace, tu récupères le bordel qui est déjà en mémoire et ça peut être tout et n'importe quoi, tu ne dois surtout pas utiliser la mémoire allouer sans l'initialiser
2. un pointeur null n'est pas nécessairement représenté par une mémoire à 0, c'est un détail d'architecture, bzero ou memset(0) sur le pointeur même, ça ne donne pas un pointeur null de manière portable

Message cité 1 fois
Message édité par masklinn le 28-01-2016 à 22:49:02

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 28-01-2016 à 23:38:40    

masklinn a écrit :

2. un pointeur null n'est pas nécessairement représenté par une mémoire à 0, c'est un détail d'architecture


Tu as un exemple concret d'architecture en tête? Je suis un peu étonné car on voit (ou en tout cas je vois) souvent des trucs genre  

Code :
  1. int *ptr;
  2. ptr=malloc(42*sizeof(int));
  3. if(!ptr) { printf("et merde!" ); return 1; }


je vois mal comment ça peut fonctionner si le pointeur NULL (que retourne malloc() en cas d'erreur, j'ai vérifié c'est bien NULL et non 0) est différent de 0. C'est un cas spécial que prends en compte le compilateur? Ou c'est moi qui n'a pas compris le problème? :o Ou mon exemple est-il faux et il faudrait utiliser un test ==NULL?
J'ai regardé dans le K&R, il n'y a qu'une mention de NULL, pas grand chose d'intéressant. Ce qui, au passage, est curieux c'est que d'après le même bouquin NULL est défini dans stdio.h, pourtant dans mon MinGW je trouve du #define NULL uniquement dans windef.h.  
Ah le C est ses subtilités...

Reply

Marsh Posté le 29-01-2016 à 09:01:58    

rat de combat a écrit :

Tu as un exemple concret d'architecture en tête?


http://c-faq.com/null/machexamp.html

rat de combat a écrit :

Je suis un peu étonné car on voit (ou en tout cas je vois) souvent des trucs genre

Code :
  1. int *ptr;
  2. ptr=malloc(42*sizeof(int));
  3. if(!ptr) { printf("et merde!" ); return 1; }


je vois mal comment ça peut fonctionner si le pointeur NULL (que retourne malloc() en cas d'erreur, j'ai vérifié c'est bien NULL et non 0) est différent de 0. C'est un cas spécial que prends en compte le compilateur? Ou c'est moi qui n'a pas compris le problème? :o Ou mon exemple est-il faux et il faudrait utiliser un test ==NULL?


L'exemple est correct, la spec C définit `if (!foo)` comme équivalent à `if (foo == 0)`. Si "foo" est un pointeur, le second membre est un "integral constant expression with the value 0" (un 0 constant litéral dans un contexte de pointeur), qui est spécifié comme générant un pointeur null. Notes que la partie "constante" est importante, c'est une conversion faite par le compilateur, un entier de valeur 0 converti pendant l'exécution (avec un cast) c'est un pointeur vers l'adresse 0, qui n'est pas nécessairement invalide (et notes que déréférencer un NP c'est une UB, c'est pas nécessairement un crash)


Message édité par masklinn le 29-01-2016 à 09:31:35

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 30-01-2016 à 17:41:40    

Ouais... :pt1cable: Je retiens simplement que mon exemple (if(!ptr) ou if(ptr==0)) est correct peu importe comment un pointeur null est représenté. Est-ce exact? (Et pour la UB, que ce soit ça ou un crash les deux ne sont pas bons...). Merci pour la réponse en tout cas.

Reply

Marsh Posté le 30-01-2016 à 17:41:40   

Reply

Marsh Posté le 30-01-2016 à 18:21:21    

rat de combat a écrit :

Ouais... :pt1cable: Je retiens simplement que mon exemple (if(!ptr) ou if(ptr==0)) est correct peu importe comment un pointeur null est représenté. Est-ce exact?


Oui.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 31-01-2016 à 11:36:21    

Certes, mais tant qu'à écrire un truc comme if (ptr == 0) autant écrire if (ptr == NULL).
 
La raison pour laquelle l'idiome C if (!ptr) est couramment utilisé, c'est pour éviter de faire la faute de frappe if (ptr = 0).
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed