akr
akr

Reputation: 1

passing strucure to function via pointer in C

typedef struct {  
    int *list;    
} List;

void list_init(List *l, int size) {   
    l=(List*) malloc(sizeof(List));
    l->list = (int*) malloc(size * sizeof(int));  
    l->list[0]=10;   //line 1
}

void main() {
    List *intlist;
    list_init(intlist,3);
    intlist->list[0]=10; //line 2
}

line 2 gives segmentation fault error but line 1 does not.

Why? Any help please.

Upvotes: 0

Views: 56

Answers (2)

VolAnd
VolAnd

Reputation: 6407

Returning the pointer from function (as R Sahu suggests) is a good solution. Another solution can be sending pointer-to-pointer to function list_init.

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

typedef struct {  
    int *list;    
} List;

// returns error code (just as example)
int list_init(List **l, int size)  // the first argument is pointer-to-pointer
{   
    int cnt;
    *l=(List*) malloc(sizeof(List));  // it is not a problem to cast poiter type
    if( *l == NULL )
    {
        return 1; // 1 means problem with allocation memory for List 
    }
    (*l)->list = (int*) malloc(size * sizeof(int));  
    if( (*l)->list == NULL )
    {
        return 2; // 2 means problem with allocation memory for int-list 
    }
    for(cnt = 0; cnt < size; cnt++)
    {
        (*l)->list[cnt] = 0;   // let it be 0 for all elements
    }
    return 0; // 0 means NO problems with allocation memory
}

int main(void) 
{
    List *intlist;
    if ( list_init(&intlist,3) == 0 ) // give address of intlist to function and check the result
    {
        intlist->list[0]=10; // now it works
    }
    else
    {
        printf("Memory cannot be allocted for List\n");
    }
}

This solution can be useful for cases when your function return something else but also should allocate memory and change the pointer.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206737

You are modifying a local copy of the pointer in list_init. It does not change the pointer in main.

I suggest (with some additional error checking code):

List* list_init(int size) {   
    List* l = malloc(sizeof(List)); // Don't cast the return value of malloc
    if ( l )
    {
       l->list = malloc(size * sizeof(int));
       if ( l->list )
       {
          l->list[0]=10;   //line 1
       }
    }
    return l;
}

void main() {
    List *intlist = list_init(3);
    if ( intList && intList->list )
    {
       intlist->list[0]=10; //line 2
    }
}

Upvotes: 2

Related Questions