Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1796 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] Stockage tableau dans Mémoire partagée

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] Stockage tableau dans Mémoire partagée

n°1737112
erasor2k5
Posté le 26-05-2008 à 11:55:56  profilanswer
 

Bonjour à tous,
 
Pourriez vous m'eclairer & me dire pourquoi ceci ne fonctionne pas:

Code :
  1. define SIZEX 10
  2. define SIZEY 10
  3. ...
  4. shm_id = shmget(key, SIZEX*SIZEY, IPC_CREAT | SHM_R | SHM_W);
  5. map = (char **)shmat(shm_id, NULL, 0);
  6. map[0][1] = 't';
  7. map[0][2] = 'e';
  8. ...
  9. map[0][5] = '\0';
  10. shmdt(map);


 
alors que ceci fonctionne:

Code :
  1. define SIZEX 10
  2. define SIZEY 10
  3. ...
  4. shm_id = shmget(key, SIZEX*SIZEY, IPC_CREAT | SHM_R | SHM_W);
  5. map = (char **)shmat(shm_id, NULL, 0);
  6. for (i = 0; i < SIZEY; i++)
  7. {
  8.           map[i] = "blablabla\0";
  9. }
  10. shmdt(map);


 
Apparement quand j'essaye de manipuler case par case ca segfault (de même pr strcpy par exemple) mais quand je lui définie une valeur directement, cela fonctionne, c'est sans doute un problème de pointeur mais là j'avoue ne pas savoir quoi faire ?
 
Merci pour votre aide!

mood
Publicité
Posté le 26-05-2008 à 11:55:56  profilanswer
 

n°1737114
bjone
Insert booze to continue
Posté le 26-05-2008 à 11:59:32  profilanswer
 

map n'est pas un char ** (pointeur sur pointeur)
 
 

n°1737144
Taz
bisounours-codeur
Posté le 26-05-2008 à 12:41:48  profilanswer
 

parce que t'es map[x] ne sont pas initialisés.

n°1737161
erasor2k5
Posté le 26-05-2008 à 13:27:57  profilanswer
 

Taz a écrit :

parce que t'es map[x] ne sont pas initialisés.


Bein meme si je les initialise de cette façon:

Code :
  1. 1. define SIZEX 10
  2.    2. define SIZEY 10
  3.    3. ...
  4.    4. shm_id = shmget(key, SIZEX*SIZEY, IPC_CREAT | SHM_R | SHM_W);
  5.    5. map = (char **)shmat(shm_id, NULL, 0);
  6.    6. for (i = 0; i < SIZEY; i++)
  7.    7. {
  8.    8.           map[i] = "blablabla\0";
  9.    9. }
  10.   10. shmdt(map);


 
et que ensuite je fasse:

Code :
  1. map[0][2] = 't';


Ca plante, pourtant en lecture ca passe nikel ??

n°1737166
bjone
Insert booze to continue
Posté le 26-05-2008 à 13:33:18  profilanswer
 

Taz a écrit :

parce que t'es map[x] ne sont pas initialisés.


ou ça, en fait ça dépends ce qu'il veut faire le monsieur  :jap:

n°1737168
erasor2k5
Posté le 26-05-2008 à 13:34:51  profilanswer
 

bjone a écrit :


ou ça, en fait ça dépends ce qu'il veut faire le monsieur  :jap:


bein moi je cherche juste à stocker des char dans un tableau, charactere par charactere ! :)

n°1737169
bjone
Insert booze to continue
Posté le 26-05-2008 à 13:36:38  profilanswer
 

moi ce qui me gène c'est ton SIZEX*SIZEY.
qu'est ce que tu veux faire, manipuler un tableau de char 2D, ou un tableau de pointeurs ?
si c'est un tableau de pointeurs char** est ok, mais la taille de la shm serait plustôt PTR_COUNT*sizeof( char* ).
 
autrement si tu comptes mettre en shm 10 chaines de 10 caractères max, tu te mets les pieds dans le tapis.

n°1737170
matafan
Posté le 26-05-2008 à 13:37:34  profilanswer
 

Comment est déclarée ta variable map ?

n°1737172
bjone
Insert booze to continue
Posté le 26-05-2008 à 13:38:49  profilanswer
 

erasor2k5 a écrit :


bein moi je cherche juste à stocker des char dans un tableau, charactere par charactere ! :)


 
ok.
 
donc  
char *map;
et pas char **map;
 
for( i = 0; i < SIZEY; i++ )
{
    char *dst_string = map + SIZEX * i;
    strncpy( dst_string, "plouf", SIZEX );
}
 
et là tu as 10 (SIZEY) ploufs tous les 10 (SIZEX) char.

Message cité 1 fois
Message édité par bjone le 26-05-2008 à 13:41:37
n°1737174
erasor2k5
Posté le 26-05-2008 à 13:39:52  profilanswer
 

bjone a écrit :

autrement si tu comptes mettre en shm 10 chaines de 10 caractères max, tu te mets les pieds dans le tapis.


 
Oui moi c'est plutot ca que je veux faire, mon map est déclaré comme un -> char **map

mood
Publicité
Posté le 26-05-2008 à 13:39:52  profilanswer
 

n°1737175
erasor2k5
Posté le 26-05-2008 à 13:41:37  profilanswer
 

bjone a écrit :


 
for( i = 0; i < SIZEY; i++ )
{
    char *dst_string = map + SIZEX * i;
    strcpy( dst_string, "plouf" );
}
 


 
Oui j'avais déja vu ca mais j'ai pas trop compri l'histoire, je vais pouvoir y acceder comme un tableau 2D après ?

n°1737177
bjone
Insert booze to continue
Posté le 26-05-2008 à 13:46:05  profilanswer
 

d'un point de vue déroulage mémoire, un tableau 2D est un tableau 1D ou les lignes sont les unes derrière les autres.
 
---
 
la confusion classique est qu'un "type **truc", c'est n'est pas un pointeur sur un tableau 2D, c'est un pointeur sur pointeur et du coup les offsets n'ont plus rien à voir.

n°1737179
erasor2k5
Posté le 26-05-2008 à 13:48:01  profilanswer
 

Oui je suis d'accord mai d'un point de vue technique est ce que je vais pouvoir le manipuler comme map[2][3], etc...après?

n°1737185
bjone
Insert booze to continue
Posté le 26-05-2008 à 13:54:23  profilanswer
 

oui et non :D
 
si tu déclares une fonction style:
 
void plop( char *ptr )
{
}
 
la taille de la ligne est "perdue", et il faut le faire à la main. style  
 
char plop( char *ptr, int x, int y )
{
   char *spot = ptr + x + y * SIZEX;
   return *spot;
}
 
par contre si tu déclares une fonction style:
 
char puick( char tab[SIZEY][SIZEX], int x, int y )
{
    return tab[y][x];
}
 
le compilo peut déterminer l'adresse correctement (si je me mets pas les pieds dans le tapis)
 
le problème étant que ça reste valide pour des dimensions statiques, mais si tu dois utiliser des dimensions variables cette approche tombe.

n°1737194
erasor2k5
Posté le 26-05-2008 à 14:06:26  profilanswer
 

Oui moi c'est statique, je défini la taille ds les define & j'y touche plus donc en principe ce serait ca pour moi...

bjone a écrit :

char puick( char tab[SIZEY][SIZEX], int x, int y )
{
    return tab[y][x];
}


 
C'est dingue quand même qu'il n'y ai aucun autre moyen de gerer ca c'est pas possible >_<
 
Ce que je comprend pas non plus c'est que pourtant quand je fait de la lecture char par char ca fonctionne

Code :
  1. int     display_map(char **map)
  2. {
  3.   int   x;
  4.   int   y;
  5.   for (y = 0; y < SIZEY; y++)
  6.     {
  7.       for (x = 0; x < SIZEX; x++)
  8. {
  9.           printf("%c ",map[y][x]);
  10.         }
  11.       printf("\n" );
  12.     }
  13. }


Donc je pointe forcément au bon endroit ? o_O  

n°1737197
bjone
Insert booze to continue
Posté le 26-05-2008 à 14:09:10  profilanswer
 

nan là tu vas mettre ton doigt dans le cul du diable :/

n°1737199
erasor2k5
Posté le 26-05-2008 à 14:10:16  profilanswer
 

t1 ca fait chier cette histoire quand même :/ foutu SHM :/  
Merci pour votre aide :))

n°1737207
bjone
Insert booze to continue
Posté le 26-05-2008 à 14:19:06  profilanswer
 

rien à voir avec les shm, ça a avoir avec l'adressage en C.
 
avec un **map comme déclaration de type,
 
un map[y][x], va chercher le y-ième (en fait +1 vu que le premier est le 0-ième) pointeur (de pointeur de char) à partir de map, puis à partir de cette adresse va chercher le x-ième pointeur.
 
avec un printf( "%c"  ), tu cast ce pointeur en en char pour l'afficher.
 
donc avoir un printf("%c ",map[y][x]), est encore plus faux que printf("%c ",*map[y][x])  
dans le premier tu affiche le pointeur casté en char, alors que dans le deuxième tu affiche un char.
 
mais vu que ton espace mémoire est en vrac, à la limite c'est moins pire. (le cul du diable ou ses laterines)
vu que map[y][x], va faire un seul accès mémoire débile (pour obtenir le pointeur [x], en supposant que le pointeur [y] soit dans l'espace de la shm)
alors que *map[y][x] te fera un double accès débile. (le pointeur[x] puis la déférence de ce pointeur pour obtenir le char de l'espace intersidéral)  
 
avec un char tab[SIZEY][SIZEX], le compilo fait ce que tu lui demande, il va chercher le char aux coordonnées x,y.

Message cité 1 fois
Message édité par bjone le 26-05-2008 à 14:22:32
n°1737211
erasor2k5
Posté le 26-05-2008 à 14:22:59  profilanswer
 

bjone a écrit :

rien à voir avec les shm, ça a avoir avec l'adressage en C.
 
avec un **map comme déclaration de type,
 
un map[y][x], va chercher le y-ième (en fait +1 vu que le premier est le 0-ième) pointeur (de pointeur de char) à partir de map, puis à partir de cette adresse va chercher le x-ième pointeur.
 
avec un printf( "%c"  ), tu cast ce pointeur en en char pour l'afficher.
 
donc avoir un printf("%c ",map[y][x]), est encore plus faux que printf("%c ",*map[y][x])  
dans le premier tu affiche le pointeur casté en char, alors que dans le deuxième tu affiche un char.
mais vu que ton l'espace mémoire est en vrac, à la limite c'est moins pire. (le cul du diable ou ses laterines)
 
avec un char tab[SIZEY][SIZEX], le compilo fait ce que tu lui demande, il va chercher le char aux coordonnées x,y.


 
Oui mais dans ce cas là je le déclare comment le tableau?

Code :
  1. char tab[SIZEY][SIZEX]
  2. void *addr;
  3. ...
  4. shm_id = shmget(key, SIZEX*SIZEY, IPC_CREAT | SHM_R | SHM_W);
  5. addr = shmat(shm_id, NULL, 0);
  6. ...
  7. tab[0][2] = 'x';
  8. tab[0][3] = 'x';
  9. ...
  10. addr = tab; ?? (ou memcpy(addr, tab, SIZEY*SIZEX))


Ca peut marcher?

Message cité 2 fois
Message édité par erasor2k5 le 26-05-2008 à 14:23:28
n°1737213
Taz
bisounours-codeur
Posté le 26-05-2008 à 14:28:09  profilanswer
 

t'as un problème de C là: . Travaille déjà à comment allouer une matrice avec un seul malloc. Ensuite tu transpose.
 
C'est moche cette histoire de * décalage.
 
Alloue N pointeurs + N x M x sizeof(Element).
Tu remplis les N pointeurs pour pointer vers le bon morceau à l'adresse i x M x sizeof(Element) et c'est bon. Après tu peux a[n][m];

n°1737214
erasor2k5
Posté le 26-05-2008 à 14:32:04  profilanswer
 

oki jvé essayer de voir ca !
 
Merci pr ton aide!

n°1737215
Taz
bisounours-codeur
Posté le 26-05-2008 à 14:32:44  profilanswer
 

erasor2k5 a écrit :


 
Oui mais dans ce cas là je le déclare comment le tableau?

Code :
  1. char tab[SIZEY][SIZEX]
  2. void *addr;
  3. ...
  4. shm_id = shmget(key, SIZEX*SIZEY, IPC_CREAT | SHM_R | SHM_W);
  5. addr = shmat(shm_id, NULL, 0);
  6. ...
  7. tab[0][2] = 'x';
  8. tab[0][3] = 'x';
  9. ...
  10. addr = tab; ?? (ou memcpy(addr, tab, SIZEY*SIZEX))


Ca peut marcher?


On à traiter 100x le cas d'allouer une matrice avec un seul malloc. Réfléchi un peu ou fais une recherche.

n°1737216
bjone
Insert booze to continue
Posté le 26-05-2008 à 14:33:06  profilanswer
 

erasor2k5 a écrit :


 
Oui mais dans ce cas là je le déclare comment le tableau?

Code :
  1. char tab[SIZEY][SIZEX]
  2. void *addr;
  3. ...
  4. shm_id = shmget(key, SIZEX*SIZEY, IPC_CREAT | SHM_R | SHM_W);
  5. addr = shmat(shm_id, NULL, 0);
  6. ...
  7. tab[0][2] = 'x';
  8. tab[0][3] = 'x';
  9. ...
  10. addr = tab; ?? (ou memcpy(addr, tab, SIZEY*SIZEX))


Ca peut marcher?


 
 
char *shm = shmat( ... )
process( shm );
 
avec:
 
void process( char tab[SIZEY][SIZEX] )
{
}
 

n°1737220
bjone
Insert booze to continue
Posté le 26-05-2008 à 14:36:14  profilanswer
 

Taz a écrit :

t'as un problème de C là: . Travaille déjà à comment allouer une matrice avec un seul malloc. Ensuite tu transpose.
 
C'est moche cette histoire de * décalage.
 
Alloue N pointeurs + N x M x sizeof(Element).
Tu remplis les N pointeurs pour pointer vers le bon morceau à l'adresse i x M x sizeof(Element) et c'est bon. Après tu peux a[n][m];


 
j'ai un peu peur qu'il se perde :)
de plus si les pointeurs sont dans la shm, il risque d'avoir des surprises.

n°1737224
Taz
bisounours-codeur
Posté le 26-05-2008 à 14:38:31  profilanswer
 

bjone a écrit :


 
j'ai un peu peur qu'il se perde :)
de plus si les pointeurs sont dans la shm, il risque d'avoir des surprises.


y a pas de raison. shm ou malloc c'est pareil. pas le peine de ce lancer dans des trucs compliqués si on ne maitrise pas.
d'ailleurs pour ce tableau de chaines, si la taille des chaines est fixe, c'est tout a fait possible de faire ça super simplement avec un pointer de char[N] et en allouer M.
 
Mais oui c'est les bases du C, pas la peine d'aller plus loin si on ne les a pas.

n°1737227
erasor2k5
Posté le 26-05-2008 à 14:39:55  profilanswer
 

Bein les malloc & tout j'ai aucun soucis, c'est juste la manipulation en mémoire qui est un peu plus nouvelle pour moi, je vais tester & voir !

n°1737230
bjone
Insert booze to continue
Posté le 26-05-2008 à 14:42:16  profilanswer
 

ce que je veux dire, c'est que le pointeur direct sur une ligne de matrice dans la shm, peut être invalide d'un process/binaire à un autre suivant où est projetée la shm dans l'espace d'adressage.  
donc un offset depuis le début de la shm oui, mais un pointeur absolu danger (dans le cas de la shm), ceci dit ça lui fera faire de l'exercice :D

Message cité 1 fois
Message édité par bjone le 26-05-2008 à 14:43:11
n°1737232
Taz
bisounours-codeur
Posté le 26-05-2008 à 14:45:38  profilanswer
 

bjone a écrit :

ce que je veux dire, c'est que le pointeur direct sur une ligne de matrice dans la shm, peut être invalide d'un process/binaire à un autre suivant où est projetée la shm dans l'espace d'adressage.  
donc un offset depuis le début de la shm oui, mais un pointeur absolu danger (dans le cas de la shm), ceci dit ça lui fera faire de l'exercice :D


c'est vrai. Vu qu'il faut bien allouer quelque chose pour que tout tienne en SHM, tes chaines sont à taille fixe. Ca se fait un un seul malloc
 

Code :
  1. #include <stdlib.h>
  2. enum { STRING_SIZE = 64 };
  3. typedef char (*STRING_ARRAY)[STRING_SIZE];
  4. STRING_ARRAY
  5. alloc(size_t n)
  6. {
  7.   return malloc(STRING_SIZE * n);
  8. }
  9. int main()
  10. {
  11.   STRING_ARRAY a = alloc(42);
  12.   return sizeof a[0];
  13. }

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] Stockage tableau dans Mémoire partagée

 

Sujets relatifs
CGI en langage C[C#] exception NullReferenceExc lors de changement d'image de fond
[C] Appeller une fonctionEffectuer des opérations sur la colonne/ligne d'un tableau
[C/C++] Problème d'écriture/lecture sur port série.Delphi compilation mémoire insuffisante
requête SQL (C++ builder 2007)Création d'un tableau
Tableau d'images cliquables[Résolu][ASP.Net / C# ]Checkbox et Controls
Plus de sujets relatifs à : [C] Stockage tableau dans Mémoire partagée


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR