Thread: Creating a dynamic list starting with an uninitialised pointer

  1. #1
    Registered User
    Join Date
    Jan 2023
    Posts
    5

    Question Creating a dynamic list starting with an uninitialised pointer

    Hey there,
    this is my first post here and I am excited to see how this goes.
    I have the following problem (code: (AuD-Ü-06) Creating List (Bugged).c):

    I want to create a list with a dynamic data structure using pointers. For that I declared a pointer type and a struct typ, which includes a value and pointer itself. I am aiming for a continuous list of these struct variables whereas the previous is linked to the next over its pointer. I want to implement a function append_list(list *l, int n) for appending a new element to the given list l with the given value n. When I use an initialised pointer, this function is working. When I use an empty pointer, the compiler doesn't complain, but the program stops with "zsh: segmentation fault" right after I entered the first value. I hope, you can help me! I am looking forward to any suggestions.
    Last edited by might_be_right; 01-27-2023 at 06:24 AM.

  2. #2
    Registered User
    Join Date
    Feb 2022
    Location
    Canada, PEI
    Posts
    103
    Your link(attachment) doesn't work.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    The attachment is only 700 bytes.
    You may as well post the code inline between [code][/code] tags.

    > When I use an initialised pointer, this function is working. When I use an empty pointer, the compiler doesn't complain,
    > but the program stops with "zsh: segmentation fault" right after I entered the first value.
    With an uninitialised pointer, you roll the dice and luck out on a valid address you can trash with your input.
    A null pointer is a guaranteed segmentation fault whenever you try to do anything with it.

    > I am looking forward to any suggestions.
    Use the debugger.
    Code:
    $ cat foo.c
    #include<stdio.h> 
    int main()
    {
        int *p = NULL;
        *p = 42;
        return 0;
    }
    $ gcc -g foo.c
    $ gdb -q ./a.out
    Reading symbols from ./a.out...
    (gdb) run
    Starting program: ./a.out 
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    
    Program received signal SIGSEGV, Segmentation fault.
    0x000055555555513d in main () at foo.c:5
    5	    *p = 42;
    (gdb) print p
    $1 = (int *) 0x0
    (gdb)
    The debugger will catch the segfault and point you at the actual line of code causing the trouble.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Jan 2023
    Posts
    5

    Post

    Sorry, apparently the file size wasn't suitable for posting as an attachement.
    Here is the code:

    Code:
    /* Creating a List */
    #include <stdio.h>
    #include <stdlib.h>
     
    typedef struct element *list;
    struct element { int value; 
                     list next; } ;
     
    int m, n;
     
    void append_list(list *l, int n)
    {
        list help;
        if (*l == NULL)
        {
            help = (list) malloc(sizeof(struct element));
            help->value = n;
            help->next = NULL;
            *l = help;
        }
        else append_list(&(*l)->next, n);
    }
     
    int main()
    {
        list start;
        printf("Please enter the length of your list: \n    m = ");
        scanf("%d", &m);
        printf("Please enter all list elements: \n");
        for (int i = 0; i < m; i++)
        {
            printf("    e(%d) = ", i); scanf("%d", &n);
            append_list(&start, n);
        }
        return 0;
    }

  5. #5
    Registered User
    Join Date
    Jan 2023
    Posts
    5
    > With an uninitialised pointer, you roll the dice and luck out on a valid address you can trash with your input.
    > A null pointer is a guaranteed segmentation fault whenever you try to do anything with it.

    Thanks for your input!
    So the problem is, that I use the NULL pointer as input for my function (or like you said "try to do anything with it")?
    That looks like quite the predicament for me. By assignment of my prof the append function has to use a pointer as its input (so basically the starting point of the list).
    I don't wanna create the first list element outside of the function and create all the other elements inside of the function. Any ideas how I could solve this?

    > Use the debugger.
    > The debugger will catch the segfault and point you at the actual line of code causing the trouble.

    Alright! I will this out

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Just initialising start to NULL, it would seem to be OK.

    A couple of style points.
    1. There's no need for m,n to be globals.
    2. There's no need to cast the result of malloc.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jan 2023
    Posts
    5
    > Just initialising start to NULL, it would seem to be OK.

    Hey Salem! Thank you so much, that’s so true. Some minutes ago I got the same idea and wanted to update this thread. Awesome that you already confirmed this theory beforehand! Guess the solution was to obvious. So happy now!

    > A couple of style points.
    > 1. There's no need for m,n to be globals.
    Alright that’s true. I was to lazy to think about the necessity of this, honestly.

    > 2. There's no need to cast the result of malloc
    Okay. Could you tell me why, please?
    I just started with C in m studies and the professor and all other tutors said that we should cast the memory allocation (so guess I just need to keep doing it, to get all the points in the exam). It’s a real shame that they taught us false stuff *annoyed*

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Casting malloc - Cprogramming.com

    > professor and all other tutors said that we should cast the memory allocation
    Yeah, maybe they're closet C++ programmers.

    If you discount the case of trying to write 30+ year old C code with a compiler from way before 1989, there are only two bad cases to worry about.
    Neither of which are solved by casting malloc.

    1. Forgetting to include stdlib.h
    Code:
    $ cat foo.c
    #include <stdio.h>
    //#include <stdlib.h>
    int main()
    {
        printf("sizeof int=%zd, sizeof ptr=%zd\n", sizeof(int), sizeof(char*));
        char *p = malloc(10);
        char *q = (char*)malloc(20);
        return 0;
    }
    $ gcc foo.c
    foo.c: In function ‘main’:
    foo.c:6:15: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
        6 |     char *p = malloc(10);
          |               ^~~~~~
    foo.c:2:1: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’
        1 | #include <stdio.h>
      +++ |+#include <stdlib.h>
        2 | //#include <stdlib.h>
    foo.c:6:15: warning: incompatible implicit declaration of built-in function ‘malloc’ [-Wbuiltin-declaration-mismatch]
        6 |     char *p = malloc(10);
          |               ^~~~~~
    foo.c:6:15: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’
    $ ./a.out 
    sizeof int=4, sizeof ptr=8
    Other compilers would be less chatty, and just implicitly declare int malloc();
    Without the cast, you would at least get a warning about an incompatible type assignment.
    With the cast, you get nothing.
    The code is thoroughly broken on machines where pointers and integers have different sizes (as is the case here).

    2. Compiling C code with a C++ compiler.
    This is an all too easy trap to fall into, if you let IDEs do the work of setting up a project for you (looking at you visual studio).
    Code:
    $ cat foo.c
    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {
        printf("sizeof int=%zd, sizeof ptr=%zd\n", sizeof(int), sizeof(char*));
        char *p = malloc(10);
        char *q = (char*)malloc(20);
        return 0;
    }
    $ gcc -xc++ foo.c
    foo.c: In function ‘int main()’:
    foo.c:6:21: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
        6 |     char *p = malloc(10);
          |               ~~~~~~^~~~
          |                     |
          |                     void*
    The cast only serves to make the compiler shut up, and completely hides the fact that you should be using a C compiler to compile C code.

    Despite what many claim, C++ is NOT a superset (either mathematical or semantic) of C.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamic List Char Array & Double Linked List
    By Roadrunner2015 in forum C Programming
    Replies: 18
    Last Post: 10-20-2013, 01:31 PM
  2. Pointer problem with linked list creating blanks.
    By uniprog in forum C Programming
    Replies: 4
    Last Post: 02-08-2013, 10:39 AM
  3. creating a list pointer of parent type from base type...
    By Adamkromm in forum C++ Programming
    Replies: 14
    Last Post: 04-14-2012, 02:07 PM
  4. Replies: 5
    Last Post: 07-28-2007, 04:03 AM
  5. creating a dynamic 2d array?
    By der dom in forum C Programming
    Replies: 11
    Last Post: 09-28-2004, 05:16 PM

Tags for this Thread