Domanda

This may be a stupid question, and I see similar questions been asked, but I dont get the answers given. why does the following code produce:

error: incompatible types when assigning to type ‘node_t’ from type ‘struct node_t *’

node_t list_array[10];
typedef struct node
{
    int value;
    struct node *next;
    struct node *prev;
} node_t;

node_t* create_node(void)
{
    node_t *np;
    np->next = NULL;
    np->prev = NULL;
    np->value = rand() % 10;
    return np;
}

int main(void)
{
int i;
for(i = 0; i < 10; i++)
{
    list_array[i] = create_node();
}
return 0;
}    
È stato utile?

Soluzione

Make the array into an array of pointers to fix the error, since create_node returns a pointer:

node_t *list_array[10];

Note you're not allocating any memory in create_node so using np is illegal. Try:

node_t *np = malloc(sizeof *np);

I want to make an array of node_t structs

In that case you could leave the node_t list_array[10] and:

  • Pass &list_array[i] as an argument to the function
  • Have the function return a node_t instead of a node_t *

Altri suggerimenti

Because one is a structure and the other is a pointer to the structure.

The create_node() function returns a pointer to a node (which you really should malloc() in that function, by the way) and you try to assign it to an actual structure in the array.

You can solve it by simply changing your declaration to:

node_t *list_array[10];

so that it's an array of pointers rather than an array of structures.

Because create_node() returns a pointer, but list_array[i] is an actual instance. You can't assign a pointer over an instance, they're completely different.

The solution is typically to represent each node as a pointer, which requires list_array to be an array of pointers:

node_t *list_array[10];

Then the assigment makes sense, and the code will compile.

Note, however, that the code will not "work", since it's dereferencing a NULL pointer inside create_node(). It seems you forgot to call malloc():

node_t* create_node(void)
{
    node_t *np;
    if((np = malloc(sizeof *np)) != NULL)
    {
        np->next = NULL;
        np->prev = NULL;
        np->value = rand() % 10;
    }
    return np;
}

This is the classic "pointer vs. instance" confusion. Even more serious than your warning is:

node_t *np;
np->next = NULL;

which will compile, and then segfault.

The confusion arises because of a misunderstanding of what a pointer is. When compiled, a pointer is just a single number, like 140734799803888. This number is used just to locate the physical chunk of data. It's a memory address.

Pointers vs. instances are confusing, and one of the first conceptual challenges you encounter in programming. So here's an analogy:

If you've ever used a GPS, it will tell you where you are (pointer) but not what you are (data). Pointers work the same way. If someone wants to shake your hand, they wouldn't shake GPS coordinates (pointer)! They'd use the GPS coordinates to locate you, then physically visit you (data) and shake your hand. That's how pointers work.

So in your code above, you declare a pointer np, but don't give it any location to keep track of. Then, you ask "use the number in np to locate my data" (but you haven't set a number for np!) In particular, np->next asks to use the location np + someOffset (which is undefined!) to find your physical data (which is nowhere), and change it.

That's why you get a seg fault.

node_t list_array[10] should be node_t *list_array[10] You have also, not malloced your node_t *np

node_t *np = malloc(sizeof(node_t));

For this program, I see no point to using dynamic storage duration (malloc). I would dispose of create_node in favour of memcpy, if you wish to keep all of your objects in static storage duration. For example,

#include <string.h>

typedef struct node
{
    int value;
    struct node *next;
    struct node *prev;
} node_t;

int main(void) {
    node_t list_array[10];
    for (int i = 0; i < sizeof (list_array) / sizeof (*list_array); i++) {
        memcpy(list_array + i,
               &(node_t){ .value = rand() % 10,
                          .next = NULL,
                          .prev = NULL },
               sizeof (*list_array));
    }
    return 0;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top