2

I am trying to implement a stack, but am not understanding the use of the opaque pointer. Here is my declaration:

/* incomplete type */
typedef struct stack_t *stack;

/* create a new stack, have to call this first */
stack new_stack(void);

And here is my stack structure and new_stack function:

struct stack_t {
    int count;
    struct node_t {
            void *data;
            struct node_t *next;
    } *head;
};

stack new_stack(void)
{
    struct stack_t new;
    new.count = 0;
    new.head->next = NULL;
    return new;
}

In my eyes, I am returning the address of the new stack, but this throws an error on compilation from returning new. What am I doing wrong?

Connor
  • 269
  • 1
  • 4
  • 13
  • The compilation error tells you. What is it? We can help you with how to read it. –  Apr 25 '15 at 22:32
  • @Hurkyl error: returning 'struct stack_t' from a function with incompatible result type 'stack' (aka 'struct stack_t *'); take the address with & return &new; – Connor Apr 25 '15 at 22:33
  • @Hurkyl but when i return &new instead, I get a warning: address of stack memory associated with local variable 'new' returned – Connor Apr 25 '15 at 22:34
  • allocate it in the heap (using `malloc`) – Diego Apr 25 '15 at 22:35
  • `return &new`. Because `new` is a struct but the function needs to return a pointer to the struct. Nothing much to do with opaque pointers. – kaylum Apr 25 '15 at 22:36
  • @Connor: The compiler is first telling you that you are not returning the correct type, and gives a possible (and also rather "mechanical") fix. In this case, the fix is actually a bug. In fact it's such a common bug to write that the compiler is trained to recognize it and warn you. – Jon Apr 25 '15 at 22:37
  • Oops, of course. You need to allocate the memory and not return a stack (local variable) location. – kaylum Apr 25 '15 at 22:38
  • possible duplicate of [Can a local variable's memory be accessed outside its scope?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – Jon Apr 25 '15 at 22:39
  • 1) `stack` is not `stack_t` 2) `new.head->next = NULL;` : `new.head` don't point to `struct node_t`. – BLUEPIXY Apr 25 '15 at 22:46
  • amongst other problems, like typedef'ing a struct (which only causes problems and solves nothing) and using a C++ reserved word with a compiler that recognizes those reserved words. I.E. 'new'. The struct is being declared on the local stack That local stack is 'invalid' when the function exits. Suggest making the local struct declaration a pointer and call malloc() to set that pointer (be sure to check (!=NULL) to assure the operation was successful. Then return the pointer (the function prototype will need to be updated to expect a pointer and not the whole struct – user3629249 Apr 25 '15 at 23:37

1 Answers1

3

You are returning the stack_t as value, but the return type of your stack_new function is stack, which is typedef struct stack_t* stack.
You need to return the pointer - change the allocation of stack_t from stack to heap by use malloc for dynamic allocation.
Don't remember to free() the stack when not needed anymore, because it is now dynamically allocated.

stack new_stack(void)
{
    struct stack_t* new = malloc(sizeof(struct stack_t));
    new->count = 0;
    new->head = NULL;
    return new;
}
Krab
  • 6,526
  • 6
  • 41
  • 78