wenincode
wenincode

Reputation: 396

what is causing segmentation fault in c code, dynamic allocation accross functions

I am trying to have dynamically allocate arrays of structures and perform operations on them but i keep running into segmentation faults. could someone help me out?

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

void *malloc(size_t size);

typedef struct {
  double x;
  double y;
} coords;

struct figure {
  char fig_name[128];
  int coordcount, size_tracker;
  coords *pointer;
} fig;

void init_fig(int n, struct figure **point)
{
  printf("%u\n", sizeof(coords));
  point[n]->pointer = malloc(sizeof(coords) * 20);  <-------SEGFAULT
  if (point[n]->pointer == NULL){
    exit(-1);
  }
  point[n]->pointer[19].x = 2;
  point[n]->pointer[0].x = 1;
  point[n]->pointer[0].y = 2;
  point[n]->pointer[7].x = 100;
}

int main()
{
  int numfigs = 1;
  struct figure * point;
  point = malloc(sizeof(struct figure) * 16);
  point = &fig;
  point[1].coordcount = 1;
  init_fig(numfigs, &point);
  return 0;
}

I labelled where the first seg fault occurs, (used ddd). what i dont get is that i can manipulate point[1] in main but not in any other function.

Upvotes: 0

Views: 724

Answers (4)

dreamcrash
dreamcrash

Reputation: 51393

Eliminate this line point = &fig;

and modify the function:

void init_fig(int n, struct figure *point)
{
  ...
  point[n].pointer = (coords*) malloc(sizeof(coords) * 20);
  ...
}

since you should pass an array of structs and not an array of pointers.

Also, add a third parameter to the init_fig function so you can pass the size of the array of points that you want to create. Like :

void init_fig(int n, struct figure *point, int size)
    {
      ...
      point[n].pointer = (coords*) malloc(sizeof(coords) * size);
      ...
    }

Therefore, making the function more reusable.

Modify also the call to that function:

init_fig(numfigs, &point); to init_fig(numfigs, point);

Upvotes: 0

valdo
valdo

Reputation: 12923

I agree with @Maxim Skurydin. Nevertheless I'd like to explain your mistake in some more details.

Reading your init_fig one assumes that the parameter you pass struct figure **point - is actually array of pointers to struct figure. And this function accesses its n'th element.

However in your main you do something else. You allocate an array of struct figure, and your point variable points to its head. Then you take the address of this local variable and call your init_fig.

Here's the problem. init_fig assumes that you pass it an array of pointers, whereas actually this "array" consists of a single element only: the local point variable declared in main.

EDIT:

How to do this properly.

  1. Leave main intact, fix init_fig.

This means that actually there's an array of figure structs. Means - a single memory block, interpreted as an array of consequent structs.

void init_fig(int n, struct figure *point)
{
  printf("%u\n", sizeof(coords));
  point[n].pointer = malloc(sizeof(coords) * 20);  <-------SEGFAULT
  if (point[n].pointer == NULL){
    exit(-1);
  }
  point[n].pointer[19].x = 2;
  point[n].pointer[0].x = 1;
  point[n].pointer[0].y = 2;
  point[n].pointer[7].x = 100;
}
  1. Leave init_fig intact. Fix main.

This means that we actually should allocate an array of pointers, every such a pointer should point to an allocated point structure.

int main()
{
  int numfigs = 1;
  struct figure ** point;
  point = malloc(sizeof(struct figure*) * 16);

  for (i = 0; i < 16; i++)
    point[i] = malloc(sizeof(struct figure));

  point[1].coordcount = 1;
  init_fig(numfigs, &point);
  return 0;
}

Upvotes: 1

Omkant
Omkant

Reputation: 9204

  struct figure * point;
  point = malloc(sizeof(struct figure) * 16);

here point is pointer pointing to memory of 16 structures in heap but in the next line you have done this

  point = &fig;

so its memory leak and also point is not pointing to that allocated region anymore

and also init_fig should be like this

void init_fig(int n, struct figure **point)

It's the problem of segfault

Upvotes: 0

Johan Lundberg
Johan Lundberg

Reputation: 27038

You allocate memory and store the pointer in point but then you forget that pointer when you assign &fig to it.

point = malloc(sizeof(struct figure) * 16);
point = &fig;

So, you are essentially trying to write fig[1], that does not make sense.

Upvotes: 0

Related Questions