函数如何返回指向堆分配对象的指针

时间:2013-12-06 07:08:45

标签: c

我正在阅读“C接口和实现”一书,这里有一段代码,我觉得有些不对劲:

    void* stack_pop(Stack stack) {
          assert(stack->count > 0);
          struct Elem* elem = stack->head;
          stack->head = elem->next;
          stack->count--;
          void* x = elem->data;
          free(elem);
          return x;
}

这是struct stack的定义:

typedef struct Stack {
       int count;
       struct Elem {
              void* data;
              struct Elem* next;
       } *head;
} Stack;

函数stack_pop返回指针,但它指向的位置?由于free(elem)会导致未定义的行为吗?

2 个答案:

答案 0 :(得分:3)

stack_pop()返回对堆栈前端所携带数据的引用,通过此stack_pop()调用将磁头弹出堆栈。

由于data被定义为指针(void *),此操作的值复制为x

void * x = elem->data;

因此释放elem(及其成员data之后完全没问题。请注意,只有引用data)到有效负载free() ed,而不是引用的有效负载本身(data指向的内容)。

另请注意,stack_pop() 未检查head是否为NULL 。在最后一个元素从堆栈中弹出后不要调用它。

答案 1 :(得分:0)

请注意,您可能在元素中使用void*以允许任何类型的数据存储在此堆栈中。因此,您的“pointer”可能不一定是指针(您可能必须转换stack_pop())。

此外,当你释放指针时,你只释放那段已分配的内存,而不管内存在其结构中可能包含的其他指针。也就是说,当你free()指针时,free不是“递归的”,它不会free() Elem内部void* data指向的内存。