Можно ли разыменовать указатель на структуру? - PullRequest
0 голосов
/ 02 февраля 2019

У меня есть двумерный массив указателей на структуры.Я пытаюсь скопировать структуры в пятна, на которые указывают другие элементы массива.Ясный способ сделать это - просто присвоить каждое значение с помощью оператора разыменования.Я не хочу делать array[0][1] = array[1][0];, потому что это присвоит адрес структуры.Поэтому мне было интересно, смогу ли я сделать

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

как более быстрый способ копирования структур?

Ответы [ 3 ]

0 голосов
/ 02 февраля 2019

Чтобы скопировать struct , достаточно простого назначения.memcpy() не требуется - и вызов этой функции не предпочтителен.

struct {
  int piece;
  int color;
} chessman;

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

С массивом указателей на struct это тоже нормально.

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;

Вспомните, чтотакая копия является мелкой копией.Приведенное ниже назначение копирует указатель на член other_data, а не содержимое того, на что ссылается other_data.

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

chessman q1, q2;

q1 = q1; 
0 голосов
/ 02 февраля 2019

Если предположить, что элементы массива (указатели) ссылаются на правильно выделенное место, то нет более эффективного способа назначения структур.

Компилятор знает размер структуры и будет выдавать наиболее эффективный код для нее.memcpy путь будет намного медленнее.

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];   
}

и полученный код:

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
0 голосов
/ 02 февраля 2019

Вы можете сделать *(array[0][1]) = *(array[1][0]);, чтобы скопировать struct-object, но вы должны будете убедиться, что array[0][1] уже указывает на некоторую память, выделенную правильно.Поэтому, если array[0][1] еще не инициализирован, вы бы написали

array[0][1] = malloc(sizeof(*array[0][1]));
*(array[0][1]) = *(array[1][0]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...