Копировать структуру в массив того же типа структуры

Я пытаюсь скопировать структуру в массив того же типа структуры.

Мои структуры

typedef struct{
    int mode; 
    int link_cnt;
    int uid;
    int gid;
    int size;
    int pointers[NUM_INODE_POINTERS];
} inode;

typedef struct{
    inode inodes[MAXFILES+1]; 
} inode_table;

Таким образом, inode_table представляет собой массив инодов. Затем я создаю их экземпляр:

inode_table inodetable;
inode rootinode;

Инициализируйте индекс и скопируйте его в массив:

inode rootinode={
            .mode=0777, 
            .link_cnt=1,
            .uid=0,
            .gid=0,
            .size=0,
            .pointers={26,0,0,0,0,0,0,0,0,0,0,0,0}
        };

memcpy(inodetable[0], &rootinode, sizeof rootinode);

Это не работает, и я получаю сообщение об ошибке в строке memcpy:

subscripted value is neither array nor pointer nor vector

Как я могу скопировать структуру rootinode в inodetable?


person user3646037    schedule 22.03.2015    source источник
comment
Кстати, есть ли особая причина, по которой вам нужен отдельный inode rootinode? В противном случае непосредственная инициализация inodetable может быть проще.   -  person Ulfalizer    schedule 22.03.2015


Ответы (4)


memcpy(inodetable.inodes[0], &rootinode, sizeof rootinode) будет работать. inodetable — это тип struct, и вы не можете индексировать их.

Другим вариантом является memcpy(&inodetable, &rootinode, sizeof rootinode), хотя явное имя члена менее запутанно.

Однако вам не нужно использовать memcpy() для копирования struct. Простое назначение будет работать:

inodetable.inodes[0] = rootinode;

Обратите внимание, что это работает только для structs, а не для массивов. (Однако это будет работать и для struct, содержащих массивы.)

Вам также нужно быть осторожным при копировании struct, содержащих указатели по значению (через memcpy() или простое присваивание). Копироваться будут только сами указатели, а не то, на что они указывают. Указатели в копии в конечном итоге указывают на то же место, что и в скопированном из struct.

person Ulfalizer    schedule 22.03.2015
comment
Но Примечание: при присваивании сгенерированный компилятором код копирования является копией shallow, как и в случае memcpy, копируются только указатели (например, .pointers), а не то, на что они указывают. - person David C. Rankin; 22.03.2015
comment
Я предполагаю, что pointers в этом случае больше похожи на блочные индексы, где не ожидается, что копия копирует блоки. :) - person Ulfalizer; 22.03.2015
comment
Здесь есть пара ошибок. Должно быть memcpy(inodetable.inodes+0, &rootinode, sizeof rootinode); (+0 избыточен). И хотя то, что есть, действительно memcpy(inodetable.inodes, &rootinode, sizeof rootinode) лучше memcpy(&inodetable, &rootinode, sizeof rootinode) конечно для новичков... - person Persixty; 12.04.2017

Я хотел бы, чтобы вы детализировали один из ответов на этот вопрос. В ответах отмечается, что при использовании memcpy копируются только указатели. Возможно ли скопировать фактические значения в структуру?

В следующем коде я пытаюсь скопировать структуру bestSol в Solutions[iScenario] для каждого сценария. Не работает нормально, Solutions в функции generateAplan правильно только для последней iScenario. Для предыдущих он сохраняет другие значения, такие как -17866.

for (iScenario = 1; iScenario <= sce; iScenario++)
    {
    Solution bestSol(curSol);  //struct
    ....
      for (iRetryNumber = 0; iRetryNumber < iNRetries; iRetryNumber++)
         {...
          if (bestSol.m_dCost < dBestObj)
              memcpy(&Solutions[iScenario], &bestSol, sizeof(bestSol));
         }
     if(iScenario == sce)
         generateAplan(Solutions);
     }
person cagi    schedule 12.04.2017

Остальные ответы ошибочны.

Чтобы выполнить версию memcpy, вам нужно передать адрес структуры, а не структуру.

Ключевая линия

memcpy(inodetable.inodes+0, &rootinode, sizeof rootinode);

нет

memcpy(inodetable.inodes[0], &rootinode, sizeof rootinode);

+0 не нужен, он просто указывает, где индекс должен располагаться для других элементов. Скопируйте в элемент ith с помощью:

memcpy(inodetable.inodes+i, &rootinode, sizeof rootinode);

Хотя, как правильно указывают другие, по определению семантика присвоения структуры в C дает тот же результат:

inodetable.inodes=rootinode;

МВЦЭ:

#include <stdio.h>
#include <memory.h>

#define NUM_INODE_POINTERS 13
#define MAXFILES 13

typedef struct{
    int mode; 
    int link_cnt;
    int uid;
    int gid;
    int size;
    int pointers[NUM_INODE_POINTERS];
} inode;

typedef struct{
    inode inodes[MAXFILES+1]; 
} inode_table;


int main(){
inode rootinode={
            .mode=0777, 
            .link_cnt=1,
            .uid=0,
            .gid=0,
            .size=0,
            .pointers={26,0,0,0,0,0,0,0,0,0,0,0,0}
   };
    inode_table inodetable;
    inodetable.inodes[0].pointers[0]=11;
    printf("pointer[0]==%d\n",inodetable.inodes[0].pointers[0]);
    memcpy(inodetable.inodes+0, &rootinode, sizeof rootinode);
    printf("pointer[0]==%d\n",inodetable.inodes[0].pointers[0]);
    return 0;
}
person Persixty    schedule 12.04.2017

person    schedule
comment
Это действительно недостаточно, чтобы гарантировать ответ. Добавьте еще пояснение или переместите это в комментарий. - person Alexis King; 23.03.2015
comment
Попробуйте объяснить ответ! - person Felipe Oriani; 24.03.2015