Search code examples
cpointersmemory-managementmallocdynamic-memory-allocation

Accessing double pointer structures in a function


I was trying to use a double pointer structure as array of structures. It was working fine when i write the entire code in main(). Below is the working code:

xkumapu@lxapp-2 cat struct2.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

typedef struct conn_s{
    int no;
    char name[32];
}conn_t;
int main(){
    int i=0, n;
    conn_t **connections;
    printf("How many students?\n");
    scanf("%d", &n);
    for(i=0;i<n;i++){

    connections[i] = (conn_t*)malloc(sizeof(conn_t));
            printf("Enter no,name of student\n");

            scanf("%d%s", &connections[i]->no, &connections[i]->name);
    }

    printf("The student details you entered are");
    for(i=0;i<n;i++){
            printf("%d      %s", connections[i]->no, connections[i]->name);
            free(connections[i]);
    }

    return 1;
}

xkumapu@lxapp-2
xkumapu@lxapp-2 ./struct2
How many students?
3
Enter no,name of student
1 pavan
Enter no,name of student
2 suresh
Enter no,name of student
3 ramesh
The student details you entered are1      pavan2      suresh3      ramesh

But, when i use the same code in a function it is not working.

xkumapu@lxapp-2 cp struct2.c  struct1.c
xkumapu@lxapp-2 vi struct1.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

typedef struct conn_s{
    int no;
    char name[32];
}conn_t;
int data(){
    int i=0, n;
    conn_t **connections;
    printf("How many students?\n");
    scanf("%d", &n);
    for(i=0;i<n;i++){

    connections[i] = (conn_t*)malloc(sizeof(conn_t));
            printf("Enter no,name of student\n");

            scanf("%d%s", &connections[i]->no, &connections[i]->name);
    }

    printf("The student details you entered are");
    for(i=0;i<n;i++){
            printf("%d      %s", connections[i]->no, connections[i]->name);
            free(connections[i]);
    }

    return 1;
}

int main(){
    data();
return 1;
}
Entering Ex mode.  Type "visual" to go to Normal mode.
:wq
"struct1.c" 41L, 874C written
xkumapu@lxapp-2 gcc -o struct123 struct1.c
xkumapu@lxapp-2 ./struct123
How many students?
3
Segmentation fault
xkumapu@lxapp-2

Can you please help me in understanding the problem.


Solution

  • connections[i] = ...
    

    This line reads from the variable connections, which is uninitialized. This causes undefined behavior in both programs. (That means anything can happen, including appearing to "work fine".)

    You can fix this by doing

    connections = malloc(n * sizeof *connections);
    

    before the loop.


    By the way:

    • <malloc.h> is not a standard header
    • You shouldn't cast malloc
    • You should check for errors (scanf can fail, malloc can fail, etc.)
    • 1 is not a portable exit status / main return value (1 indicates an error on unix and windows, but the only portable codes are 0 and EXIT_SUCCESS for success and EXIT_FAILURE for error).
    • Passing &connections[i]->name to scanf %s is wrong: %s takes a char * but &connections[i]->name is a char (*)[32] (to fix this, remove the &)