0

I am new bee to C. I am currently writing linked list in C. When compiling, it keeps complaining about "assignment from incompatible pointer type". My code is like this:

# include <stdio.h>
#include <stdlib.h>

struct snode{
  struct snode *next;
  int val;
};

struct slist{
  struct snode *head;
  struct snode *tail;
  int len;
};

struct slist *mylist;

void slist_insert(int v){
  struct snode *newnode;
  newnode = (struct snode*)malloc(sizeof(struct snode));
  newnode -> val = v;
  newnode -> next = NULL;


  if(mylist->head  = NULL){
    mylist->head  = malloc (sizeof(struct snode));
    mylist->tail = (struct snode*)malloc (sizeof(struct snode));
    mylist->head = newnode;
    mylist->tail = newnode;
    
  };

  else{
    mylist -> tail -> next = (struct snode*)malloc (sizeof(struct snode));
    mylist -> tail -> next = newnode;
  };
   mylist -> len +=1;  
};


main(){
    slist_insert(1);
    slist_insert(2);
    slist_insert(3);
    slist_insert(4);
    slist_insert(5);

    struct snode *temp;
    temp = (struct snode*)malloc(sizeof(struct snode));
    temp = mylist-> head;
    while(temp -> next != NULL){
      printf("%d\n", temp -> val);
      temp  = temp -> next;
    };
  };
    

Here is the modified one. I am using linux terminal to run this program. The compiler I am using is gcc -std=gnu99

UPDATE

slist.c: In function â:
slist.c:32: error: â without a previous â
slist.c: At top level:
slist.c:40: warning: return type defaults to â
12
  • Start by initializing your mylist pointer to NULL on its declaration line, or you're already jumping into the pool of undefined behavior. Honestly if it is a global it shouldn't even be a pointer in the first place. the node-chain yes, mylist no. Commented Sep 1, 2013 at 20:51
  • 1
    @simonc on that regard, the two consecutive lines following the head == NULL condition.. /facepalm Commented Sep 1, 2013 at 20:55
  • 1
    @WhozCraig yep, although is there not also a head=NULL assignment in conditional problem there? Commented Sep 1, 2013 at 20:56
  • 1
    @simonc ouch. you're totally right. Can't see the forest for the tree kinda thing, I guess. Didn't even notice. Commented Sep 1, 2013 at 20:57
  • 1
    @WhozCraig C99 6.7.8p10 "If an object that has static storage duration is not initialized explicitly, then [it is initialized to a type-appropriate zero]." 6.2.4p3 defines static storage duration as applying both to objects declared explicitly static, and all objects "with external or internal linkage", which encompasses everything you're thinking of as "global". (The C standard doesn't ever use the term "global variable"; the closest match is "object with external linkage".) Commented Sep 1, 2013 at 21:03

2 Answers 2

4

There are many problems with this code. I am ONLY listing the problems that cause the "assignment from incompatible pointer" warnings. Compile with gcc -W -Wall and fix all the warnings. And after you've done that there will still be bugs.

  1. You need #include <stdlib.h>, right after the existing #include <stdio.h>, to make the declaration of malloc visible. (If you don't do this, the compiler is obliged to assume that malloc returns int, even though it knows perfectly well that that's wrong. This is what the "incompatible implicit declaration of built-in function ‘malloc’" warning is trying to tell you.)

  2. You are incorrectly casting struct snode allocations to struct slist * and then assigning them to struct snode * fields, in several places. Do not cast the return value of malloc to anything; just assign it. (Note that you may see people deliberately casting the return value of malloc in code that needs to be compilable as C++ as well as C. Do not do this until you are experienced enough to understand when it is necessary. If your compiler insists on treating everything as C++ even when it's meant to be C, get a better compiler.)

  3. struct snode's next field should be declared as struct snode *, not int *.

Sign up to request clarification or add additional context in comments.

8 Comments

please check the update. Seems there is something wrong after I changed it. It is complaining you cant use snode before you declare it.
Thanks for providing error messages, but you have some kind of character encoding problem, which has destroyed critical information. (If you're not on Windows, try typing export LC_ALL=C at the shell prompt (exactly as shown) and then re-running the compiler. If you are on Windows, do the same thing but without the export, I think.) Also, the line numbers don't seem to match the code you provided. This means I don't know what's wrong. Please correct.
... Actually, a stab in the dark: You have to write struct snode *, not just snode *.
I am using linux to run this program. Just in case I am using gcc -o to compile the program. I will update my code again.Thanks for the help!
... Are you using tcsh? If so, switch to bash or zsh immediately. (And in the meantime, try setenv LC_ALL C.) I observe that you are still casting the return value of malloc; remove all of those casts completely. Anyhow, your remaining error messages do not include anything about incompatible pointer types. If you cannot figure out what is still wrong, please ask a new question. If you want someone to go through this program line by line and point out all of the remaining bugs (which are many), please go to codereview.stackexchange.com .
|
2

Your nextis a pointer to int, while you want it to be a pointer to struct snode, I assume. Moreover, I assume that your mylist is supposet to be an slist instead of a pointer to an slist. And as has been pointed out in the comments, that membres of that mylist are not necessarily initialized (implementaiton dependent. With your mode of using a pointer for mylist, you need to malloc (and init) that guy first ...

10 Comments

But can I have a new snode in snode? I mean its not even built yet
@NobWong You are declaring the type only. Ponters are an exception to the rule that the type must be completely "known" at the moment of usage. That's because pointers are always the same size, no matter what they point to, hence the layout of the snode structure can be computed fine.
Stress data pointers are the same size, which can be different than code pointer sizing, though not particularly applicable in this usage.
@WhozCraig (1/2) POSIX requires all pointers to be the same size, and the only non-POSIX-compliant system you're likely to encounter nowadays is Windows, whose de facto ABIs also all have all pointers the same size. Having said that, the C standard requires only that all object pointers be convertible to void * and back without loss of information, and (implicitly, requiring a regrettable amount of close-reading to discover) that all pointers-to-struct-or-union types are the same size.
@WhozCraig (2/2) Historically, the most common case of pointers not being all the same, that I know about, was char * and void * being bigger than everything else (for a word-addressed machine). </pedant>
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.