1
votes

Est-il possible de déréférencer un pointeur vers une structure?

J'ai un tableau bidirectionnel de pointeurs vers les structures. J'essaie de copier les structures vers des points pointés par d'autres éléments du tableau. Pour moi, la manière la plus claire de le faire est simplement d'attribuer chaque valeur à l'aide de l'opérateur de déréférence. Je ne veux pas faire array [0] [1] = array [1] [0]; car cela attribuerait l'adresse de la structure. Je me demandais donc si je pouvais faire

*array[0][1] = *array[1][0];

comme moyen plus rapide de copier des structures?

c

9 commentaires

utilisez memcpy pour copier la taille de la structure


J'ai un tableau bidimensionnel de pointeurs vers les structures. J'essaye ... s'il vous plaît nous montrer les définitions, comme code source.


Que signifie exactement "copier la valeur des pointeurs vers d'autres points du tableau"? Qu'est-ce qui fonctionne ou ne fonctionne pas avec la solution que vous avez déjà essayée, indiquée dans la question? Pouvez-vous montrer un morceau de code plus complet?


La «valeur d'un pointeur» est l'adresse. Si vous «essayez de copier la valeur des pointeurs», vous copiez les pointeurs. Puis en disant "Je ne veux pas faire array [0] [1] = array [1] [0]; car cela attribuerait l'adresse de la structure." est incohérent, car vous venez de nous dire que vous souhaitez copier (attribuer) les adresses. Si vous voulez copier les structures, pas les adresses, vous devriez avoir écrit «J'essaye de copier les structures vers lesquelles pointent les pointeurs». Votre question n'est donc pas claire. De plus, * (array [0] [1]) ne déréférencera pas le tableau; il déréférence un élément.


Je m'excuse, c'est censé représenter un échiquier. Je comprends que la valeur d'un pointeur est l'adresse. Chaque pointeur pointe vers une structure qui représente une pièce. Ainsi, copier l'adresse dans un autre index du tableau donnerait l'impression que la pièce est là deux fois. J'aurais dû être plus précis et dire que je voulais copier le contenu du pointeur dans le nouvel index du tableau. @EricPostpischil


Vous le faites toujours. Une phrase de votre commentaire dit que vous ne voulez pas copier l'adresse, car "copier l'adresse ... donnerait l'impression que la pièce est là deux fois." Une autre phrase indique que vous souhaitez copier l'adresse, car elle indique "Je voulais copier le contenu du pointeur". Arrêtez d'écrire le «contenu du pointeur». Si vous voulez dire la structure, dites "la structure" ou "le contenu de la structure" ou "l'objet pointé par le pointeur".


De même, vous ne pouvez pas copier «le contenu du pointeur» dans «le nouvel index du tableau». Dans array [0] [1] , les indices des tableaux sont 0 et 1, et vous ne pouvez pas copier le contenu du pointeur dans 0 ou dans 1. Les choses qui sont dans le tableau sont des éléments , pas des indices. Vous voulez soit copier des pointeurs vers des éléments de tableau, soit copier des structures (pointées par des éléments de tableau) vers des structures (pointées par des éléments de tableau).


Je suis désolé. Je veux copier les structures pointées par les éléments du tableau. Je ne souhaite pas copier l'adresse. Désolé pour mon utilisation abusive des termes. Merci d'avoir rectifié mes erreurs. @EricPostpischil


@PierreEmmanuelLallemant: Pourquoi recommandez-vous memcpy ? L'affectation simple fonctionne pour les structures.


3 Réponses :


0
votes

Vous pouvez faire le * (array [0] [1]) = * (array [1] [0]); pour copier un struct-object, mais vous devrez vous assurer que array [0] [1] pointe déjà vers une mémoire allouée correctement. Donc, si array [0] [1] n'a pas été initialisé jusqu'à présent, vous écrirez

array[0][1] = malloc(sizeof(*array[0][1]));
*(array[0][1]) = *(array[1][0]);


0 commentaires

1
votes

Pour copier une struct , une simple affectation convient. memcpy () n'est pas nécessaire - et cet appel de fonction n'est pas non plus préféré.

struct {
  int piece;
  int color;
  foo *other_data;
} chessman2;

chessman q1, q2;

q1 = q1; 

Avec un tableau de pointeurs vers une struct , c'est OK aussi.

chessman *array[8][8] = { 0 };

array[1][0] = malloc(sizeof *(array[1][0]));
assign_data(array[1][0]);

array[0][1] = malloc(sizeof *(array[0][1]));
assign_data(array[0][1]);
...
chessman empty = { 0 };
*array[0][1] = *array[1][0];
*array[1][0] = empty;

Rappelez-vous qu'une telle copie est une copie superficielle. L'affectation ci-dessous copie le pointeur dans le membre other_data , et non dans le contenu de ce que fait référence other_data .

struct {
  int piece;
  int color;
} chessman;

chessman p1, p2;
...
p1 = p2;


1 commentaires

Merci pour votre aide



0
votes

En supposant que les éléments du tableau (pointeurs) référencent l'endroit correctement alloué, il n'y a pas de moyen plus efficace d'attribuer des structures.

Le compilateur connaît la taille de la structure et émettra le code le plus efficace pour celle-ci. memcpy manière sera beaucoup plus lente.

foo:
        mov     rdx, QWORD PTR d[rip+32]
        mov     rax, QWORD PTR d[rip+16]
        movdqu  xmm0, XMMWORD PTR [rdx]
        movups  XMMWORD PTR [rax], xmm0
        mov     rdx, QWORD PTR [rdx+16]
        mov     QWORD PTR [rax+16], rdx
        ret
foo1:
        mov     rdx, QWORD PTR f[rip+32]
        mov     rax, QWORD PTR f[rip+16]
        movdqu  xmm0, XMMWORD PTR [rdx]
        movups  XMMWORD PTR [rax], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+16]
        movups  XMMWORD PTR [rax+16], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+32]
        movups  XMMWORD PTR [rax+32], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+48]
        movups  XMMWORD PTR [rax+48], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+64]
        movups  XMMWORD PTR [rax+64], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+80]
        movups  XMMWORD PTR [rax+80], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+96]
        movups  XMMWORD PTR [rax+96], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+112]
        movups  XMMWORD PTR [rax+112], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+128]
        movups  XMMWORD PTR [rax+128], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+144]
        movups  XMMWORD PTR [rax+144], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+160]
        movups  XMMWORD PTR [rax+160], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+176]
        movups  XMMWORD PTR [rax+176], xmm0
        movdqu  xmm0, XMMWORD PTR [rdx+192]
        movups  XMMWORD PTR [rax+192], xmm0
        ret
foo2:
        mov     rsi, QWORD PTR n[rip+32]
        mov     ecx, 138
        mov     rdi, QWORD PTR n[rip+16]
        rep movsq
        ret

et le code résultant:

typedef struct 
{
    int a;
    double b;
    char c;
}a;

typedef struct 
{
    int a[5];
    double b[10];
    char c[100];
}b;

typedef struct 
{
    int a[50];
    double b[100];
    char c[100];
}l;


volatile a c[5];
volatile a *d[5] = {&c[0], &c[1], &c[2], &c[3], &c[4]};

volatile b e[5];
volatile b *f[5] = {&e[0], &e[1], &e[2], &e[3], &e[4]};

volatile l m[5];
volatile l *n[5] = {&m[0], &m[1], &m[2], &m[3], &m[4]};


void foo(void)
{
    *d[2] = *d[4];
}

void foo1(void)
{
    *f[2] = *f[4];
}

void foo2(void)
{
    *n[2] = *n[4];   
}

p>


0 commentaires