0

I can't understand why this simple code doesn't run without causing a segmentation fault on linux :

#include <stdlib.h>

struct entry
{
   int value;
};

void initEntry(struct entry *entry)
{
  entry = malloc(sizeof(struct entry));    
  entry->value = 0;
}

int main()
{
  struct entry *list;

  initEntry(list);    
  list->value = 5;
}

I can run the program after removing the last instruction (list->value = 5;)

I compile with :

gcc main.c -o main
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
holo
  • 331
  • 2
  • 13
  • because in C, everything is pass by value. so the value `entry` inside `initEntry` is assigned to the return from malloc, but the value `entry` inside `main` never changes. so you have both a memory leak and a crash. – MFisherKDX May 03 '18 at 15:22
  • 2
    Possible duplicate of [Changing address contained by pointer using function](https://stackoverflow.com/questions/13431108/changing-address-contained-by-pointer-using-function) – MFisherKDX May 03 '18 at 15:23
  • Be careful though, the accepted answer suggests to call Malloc inside a function, but better practice is to havr thr base pointer provided by Malloc around in case you need to `free` it – rostamn739 May 03 '18 at 18:27
  • to change the place a pointer is pointing to, via a function, the address of the pointer must be passed – user3629249 May 04 '18 at 09:50
  • when calling any of the heap allocation functions: `malloc` `calloc` `realloc` always check (!=NULL) the returned value to assure the operation was successful. If not successful, then call `perror()` with your error message, then both your message and the text reason the system thinks the error occurred are output to `stderr` – user3629249 May 04 '18 at 09:52
  • Yeah thanks you I'll think about it – holo May 04 '18 at 20:51

1 Answers1

6

You need to change it to:

void initEntry(struct entry **entry) {
  *entry = malloc(sizeof(struct entry));    
  (*entry)->value = 0;
}

int main() {
  struct entry *list;    
  initEntry(&list);    
  list->value = 5;
}

In your code you just lose the address of allocated memory after returning from the initEntry() call. It's because entry argument is a local variable regarding the initEntry() function and assigning of any values to it is invisible from outside. You need an extra inderection level to be able to return the address of the allocated memory.

Ivan Velichko
  • 6,348
  • 6
  • 44
  • 90
  • The code run but i have these messages during the compilation : `main.c:31:13: warning: passing argument 1 of ‘initEntry’ from incompatible pointer type [-Wincompatible-pointer-types] initEntry(&list); ^ main.c:24:6: note: expected ‘struct entry *’ but argument is of type ‘struct entry **’ void initEntry(struct entry *entry) {` – holo May 03 '18 at 15:28
  • 1
    Are you sure that you have adjusted both `initEntry()` definition and the `initEntry()` invocation sides? – Ivan Velichko May 03 '18 at 15:31