C通用链表

Cod*_*lus 3 c generics malloc pointers linked-list

我有一个通用的链表,其中包含void*类型的数据我试图使用struct employee填充我的列表,最终我想破坏对象struct employee.

考虑这个通用的链表头文件(我用char*类型测试过它):

struct accListNode                 //the nodes of a linked-list for any data type
{
  void *data;                     //generic pointer to any data type
  struct accListNode *next;       //the next node in the list
};

struct accList                    //a linked-list consisting of accListNodes
{
  struct accListNode *head;
  struct accListNode *tail;
  int size;
};

void accList_allocate(struct accList *theList);           //allocate the accList and set to NULL
void appendToEnd(void *data, struct accList *theList);    //append data to the end of the accList
void removeData(void *data, struct accList *theList);         //removes data from accList
  --------------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

考虑员工结构

struct employee 
{ 
   char name[20]; 
   float wageRate; 
} 
Run Code Online (Sandbox Code Playgroud)

现在考虑将从main()调用的示例测试用例:

    void test2()
    {
      struct accList secondList;
      struct employee *emp = Malloc(sizeof(struct employee));
      emp->name = "Dan";
      emp->wageRate =.5;

      struct employee *emp2 = Malloc(sizeof(struct employee));
      emp2->name = "Stan";
      emp2->wageRate = .3;

      accList_allocate(&secondList);
      appendToEnd(emp, &secondList);
      appendToEnd(emp2, &secondList);

      printf("Employee: %s\n", ((struct employee*)secondList.head->data)->name);   //cast to type struct employee
      printf("Employee2: %s\n", ((struct employee*)secondList.tail->data)->name);  
    }
Run Code Online (Sandbox Code Playgroud)

为什么我在下面发布的答案解决了我的问题?我相信它与指针和内存分配有关.我使用的函数Malloc()是一个自定义malloc,它检查返回的NULL.

以下是我的整个通用链表实现的链接:https://codereview.stackexchange.com/questions/13007/c-linked-list-implementation

Spa*_*key 6

问题是这个accList_allocate()和你使用它.

struct accList secondList;
accList_allocate(&secondList);
Run Code Online (Sandbox Code Playgroud)

在原始test2()中,secondList是堆栈上的内存.&secondList是指向该内存的指针.当你调用accList_allocate()时,指针的副本将指向堆栈内存.然后,Malloc()返回一块内存并将其分配给指针的副本,而不是原始的secondList.

退出后,secondList仍指向堆栈上未初始化的内存,因此对appendToEnd()的调用失败.

除了secondList恰好没有垃圾之外,答案也是如此.可能是偶然的,可能是通过编译器的设计.无论哪种方式,它都不是你应该依赖的东西.

或者:

struct accList *secondList = NULL;

accList_allocate(&secondList);
Run Code Online (Sandbox Code Playgroud)

并更改accList_allocate()

accList_allocate(struct accList **theList) {
    *theList = Malloc(sizeof(struct accList));
    (*theList)->head = NULL;
    (*theList)->tail = NULL;
    (*theList)->size = 0;
}
Run Code Online (Sandbox Code Playgroud)

要么

struct accList secondList;

accList_initialise(secondList);
Run Code Online (Sandbox Code Playgroud)

随着accList_allocate()更改为accList_initialise(),因为它没有分配

accList_initialise(struct accList *theList) {
    theList->head = NULL;
    theList->tail = NULL;
    theList->size = 0;
}
Run Code Online (Sandbox Code Playgroud)