3

I'm trying to allocate memory for a pointer, but have a reference to the address of that pointer. I'm still pretty new to C and this is my first time working with double pointers really. So I have two structures and they look like this:

typedef struct myNodes {
   int data;
   struct myNodes *next;
} listElement;


typedef struct {
   listElement **ptrToElements;
} myStruct;

In another file, I'm trying to dynamically allocate memory for my pointer by doing something like this:

myStruct *myStruct = malloc(sizeof(*myStruct));
*(myStruct->ptrToElements) = (listElement*)malloc(sizeof(listElement));

but I keep encountering a segmentation fault from doing so. What could be the issue? Thanks!

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 4
    Yeah...typederf a type and variable with same name.....sigh... – Sourav Ghosh Feb 05 '19 at 11:46
  • Don't cast the return value of `malloc()`! – harper Feb 05 '19 at 11:47
  • @SouravGhosh While it can confuse having the same name for typedef and variable, it doesn't give any wrong result because the pointer variable is de-referenced and the sizeof gives the correct size; – harper Feb 05 '19 at 11:50
  • 3
    @harper It confuses people. I'd say that's reason enough for being _wrong_. – Sourav Ghosh Feb 05 '19 at 11:51
  • Why to create a second struct (a.k.a myStruct) ? you can simple use listElement in your program to create a list.( list of pointers as variable). It's easier and it does the job. – TassosK Feb 05 '19 at 11:54
  • Why the double pointer here: `listElement **ptrToElements;`? – alk Feb 05 '19 at 12:09

3 Answers3

3

The problem is with

*(myStruct->ptrToElements) ....

statement. Before dereferencing myStruct->ptrToElements, you need to make sure it points to a valid memory.

To elaborate, you allocate memory for myStruct. Fine.

That constitutes allocating memory for the member ptrToElements. Good.

  • Question: What does ptrToElements points to?

  • Answer: Indeterministic.

So, when you try to derefernce a pointer which points to an indeterministic memory address, it's pretty much invalid memory address and attempt to do so will invoke undefined behavior.

Solution: You need to allocate memory for myStruct->ptrToElements before you can go ahead and dereference it.

having said that, please see do I cast the result of malloc?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
-1

I think this is what you want:

typedef struct myNodes {
   int data;
   struct myNodes *next; // not clear what this pointer is used for...
} listElement;

typedef struct {
   listElement *ptrToElements;
} myStruct;


// Memory Allocation
// allocate myStruct pointing to an array of N listElements
myStruct      *ms = malloc(sizeof(myStruct));
ms->ptrToElements = malloc(N * sizeof(listElement));

// element access
for (int i = 0; i < N; i++) {
    listElement *le = ms->ptrToElements[i];
    le->data = ...
    le->next = NULL; // not clear what this pointer is used for...
}

// Memory deallocation
free(ms->ptrToElements);
free(ms);
Stefan Becker
  • 5,695
  • 9
  • 20
  • 30
-1

You define the structure to contain a pointer to a pointer to a listElement

typedef struct {
   listElement **ptrToElements;
} myStruct;

As Sourav Ghosh wrote, you try to assign a value to the pointer where ptrToElements would point to without allocating memory.

Probably you should change the pointer type to

typedef struct {
   listElement *ptrToElements;
} myStruct;

and when allocating the memory

myStruct *myStruct = malloc(sizeof(*myStruct));
/* If the list can be empty, initialize root with NULL pointer */
myStruct->ptrToElements = NULL;

/* when you add the first list element */
myStruct->ptrToElements = malloc(sizeof(listElement));
myStruct->ptrToElements->data = someValue;
/* at least for the last element you add here you should initialize next */
myStruct->ptrToElements->next = NULL;

Don't forget to handle errors, e.g. malloc returning NULL.

Bodo
  • 9,287
  • 1
  • 13
  • 29