0
votes

Attribuer un pointeur à un tableau vide 2D dans une structure en C99

J'ai un tampon 2d que je voudrais passer à un thread avec d'autres valeurs, donc je dois le déplacer dans une structure. Lorsque j'essaie de faire cela, je ne peux pas accéder à nouveau aux valeurs de ma structure et j'ai besoin d'aide.

Voici mon tampon:

main.c:104:47: warning: dereferencing ‘void *’ pointer [enabled by default]
           fprintf(stderr, "%p\n", args->mybuff[0][0]);
                                               ^
main.c:104:50: error: subscripted value is neither array nor pointer nor vector
           fprintf(stderr, "%p\n", args->mybuff[0][0]);
                                                  ^

Je voudrais stocker un pointeur vers ce tableau 2D dans une structure comme celle-ci:

    arg_struct_t *args = malloc(sizeof(arg_struct_t));
    args->i = index;
    args->mybuff = mybuff;

    fprintf(stderr, "%p\n", args->mybuff[0][0]);

Cependant si j'essaye d'accéder aux valeurs:

typedef struct  {
  int i;
  void *mybuff;
} arg_struct_t;

J'obtiens une erreur:

void* mybuff[8][16384];

Je pense que je dois en dire plus à C99 sur la forme des données que je veux mettre dans ma structure, mais je n'arrive pas à comprendre la bonne façon de le faire. J'apprécie toute aide ou idée ici.


2 commentaires

Lorsque vous stockez mybuff dans la structure, vous perdez toutes les informations de type. Vous devez donc restaurer ces informations en attribuant args-> mybuff à un pointeur du type correct, par exemple void * (* myptr) [16384] = args-> mybuff .


concernant: void * mybuff [8] [16384]; Ceci déclare un tampon de 64K pointeurs. C'est ce que tu voulais vraiment. Remarque: sur une architecture 32 bits, cela donne 64k * 4 octets sur la pile. Ce n'est pas une bonne idée de placer autant de données sur la pile


3 Réponses :


1
votes

Au risque de vous dépasser:

typedef struct  {
  int i;
  void* mybuff[8][16384];
} arg_struct_t;

Mais la nature générale de void * est un typage générique qui est contraire aux tableaux multidimensionnels. Ce code semble étrange dès que ce type apparaît et il y a probablement autre chose qui ne va pas.


0 commentaires

1
votes

Voici comment stocker l'adresse de mybuff et comment utiliser ce pointeur ultérieurement pour accéder aux valeurs.

int main()
{
    // Starting array    
    int* mybuff[8][16384];

    // Save the address of mybuff into 'p'. 'p' is a pointer to (int*)'s
    int** p = &mybuff[0][0];

    // Access the location of row=3, col=4 using 'p'
    int r = 3;
    int c = 4;
    *(p + (r*16384 + c)) = (int*) 123; // 123 is the value to assign

    return 0;
}

Vous devrez donc également transmettre les tailles de ligne et de colonne (8 et 16384) dans votre structure également afin de déréférencer les valeurs. J'ai omis de vérifier dans l'exemple par souci de concision, mais vous devriez le faire dans du vrai code.


0 commentaires

2
votes

Le compilateur ne sait pas quelle adresse en mémoire il doit calculer ici:

typedef void* TBuff[8][16834];
TBuff mybuff;

typedef struct  {
  int i;
  TBuff * mybuff;
} arg_struct_t;

arg_struct_t *args = malloc(sizeof(arg_struct_t));
args->i = index;
args->mybuff = &mybuff;
fprintf(stderr, "%p\n", (*args->mybuff)[0][0]);

car args-> mybuff n'est qu'un pointeur vers void. Pour traiter une telle expression, le compilateur a besoin d'informations sur 1) la taille des éléments du tableau et 2) au moins une des dimensions du tableau. Le code suivant est plus correct:

args->mybuff[0][0]


2 commentaires

@ M.M, pourquoi l'indirection * mybuff ? J'ai seulement remarqué et corrigé maintenant que j'ai utilisé la variable mybuff au lieu du champ args-> mybuff .


masquer un pointeur dans un typedef est une très mauvaise pratique de programmation