memcpy / sub список связанных списков с использованием указателей - PullRequest
0 голосов
/ 14 февраля 2020

В устаревшей программе, над которой я работаю, есть несколько структур для связанных списков:

typedef struct Unit_Cell
{
    short           Type ;
    char            Name[x] ;
    short           X ;
    short           Y ;
    struct Unit_Cell *Next;
} Unit_Cell ;

typedef struct
{
    Unit_Cell    *Start;
    Unit_Cell    *Current;
} List_Cell;

У меня есть указатель на структуру List_Cell, которая содержит все ячейки.

List_Cell *FullList; # malloc'ed, with added elements etc etc

Для новой разработки мне необходимо связать подмножество этого полного списка с новыми структурами, которые выглядят следующим образом: (упрощенно)

typedef struct Unit_NewElement
{
    char            Name[y];
    int             Value;
    List_Cell      *ListCells;
    struct Unit_NewElement *Next;
} Unit_NewElement;

typedef struct
{
    Unit_NewElement   *Start;
    Unit_NewElement   *Current;
} List_Cell;

Создание нового элемента в виде:

Unit_NewElement *NewElement; # malloc'ed, with added elements etc etc ... # EXCEPT LIST CELLS !

Зацикливаясь на полном списке ячеек, я делаю расчеты, чтобы узнать, должна ли ячейка Current быть связана с моей структурой элементов.

В основном , мы бы сделали что-то вроде:


# Keeping the last element
Unit_Cell *Temp = NewElement->ListCells->Current;

# Replacing last element
NewElement->ListCells->Current = FullList->Current;

# Setting temp element (which is now our previous), next pointer to the new current
Temp->Next = NewElement->ListCells->Current;

Но, делая это, я буквально ломаю исходный список "FullList". Что мне не нужно.

Мне нужно иметь возможность добавлять ячейки из полного списка для каждого нужного мне нового элемента, без влияния на сам полный список.

Memcpy - это путь к go?

memcpy(Element->ListCells->Current, FullList->Current, sizeof(Unit_Cell));

Как справиться с тем фактом, что в копируемой структуре также есть указатель?

А как насчет прямое копирование данных без memcpy:

*Element->ListCells->Current = *FullList->Current;

Спасибо

1 Ответ

0 голосов
/ 14 февраля 2020

Я думаю, что вам нужно сделать, чтобы получить реальную копию списка, это комбинация malloc и memcpy, также скопированный указатель Next должен быть перезаписан.

Поскольку Я не знаю, как создается ваш подсписок, я предложил что-то вроде заданной начальной ячейки и количество копируемых ячеек - тогда вы могли бы сделать что-то вроде этого:

ListCell *copyList(UnitCell *from, int n)
{
   int i = 0;

   if (!from || n <= 0)
      return NULL;

   ListCell *newList = (ListCell*)malloc(sizeof(ListCell));
   newList->Start = NULL;
   newList->Current = NULL;

   while (from && i++ < n)
   {
      if (!newList->Start)
      {
          newList->Start = (UnitCell*)malloc(sizeof(UnitCell));
          memcpy(newList->Start, from, sizeof(UnitCell));
          newList->Current = newList->Start;
      }
      else if (newList->Current)
      {
          newList->Current->Next = (UnitCell*)malloc(sizeof(UnitCell));
          memcpy(newList->Current->Next, from, sizeof(UnitCell));
          newList->Current = newList->Current->Next;
      }

      from = from->Next;
   }

   // Next-pointer of last cell still points to source list cell
   if (newList->Current)
      newList->Current->Next = NULL;

   return newList;
}

(я на самом деле не проверял это код, так что могут остаться некоторые ошибки)

...