Ryan
Ryan

Reputation: 688

Inserting and Manipulating Dynamic Array of Struct Pointers

Here is what I am trying to do:
1. Create an array of struct pointers.
2. Fill the array with malloc'd structs.
3. Then replace one element in the array with a new malloc'd struct
4. Have no memory leaks.

I have written a test program below, but I am getting seg faults due to invalid reads and writes on my call to memcpy. What am I doing wrong?

#include <stdlib.h>
#include <string.h>
struct my_struct {
    int a;
    int b;
};
int main(int argc, char *argv[])
{
    struct my_struct **my_arr;
    my_arr = (struct my_struct **) malloc(10 * sizeof(struct my_struct *));
    int i;
    for (i = 0; i < 10; i++) {
        struct my_struct *my_str = (struct my_struct *) malloc(sizeof(struct my_struct *));
        my_arr[i] = my_str;
    }
    free(my_arr[0]);
    memcpy(my_arr[0], my_arr[1], sizeof(struct my_struct *) * 9);
    my_arr[9] = (struct my_struct *) malloc(sizeof(struct my_struct *));
    for (i = 0; i < 10; ++i) {
        free(my_arr[i]);
    }
    free(my_arr);
}

Upvotes: 2

Views: 141

Answers (2)

ameyCU
ameyCU

Reputation: 16607

free(my_arr[0]);
memcpy(my_arr[0], my_arr[1], sizeof(struct my_struct *) * 9);

This is problem , you first free(my_arr[0]) and then copy my_arr[1] at address it points to .

You are not supposed to access memory after freeing it . And also specified in manpage

[...]The memory areas must not overlap. Use memmove if the memory areas do overlap.

again you do this -

   my_arr[9] = (struct my_struct *) malloc(sizeof(struct my_struct *));

thus , loosing reference to previous memory block it was pointing to .

Upvotes: 1

Mike -- No longer here
Mike -- No longer here

Reputation: 2092

This code works and I cleaned it up a bit:

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

struct my_struct {
  int a;
  int b;
};
int main(){
  const int structsz=sizeof(struct my_struct);
  struct my_struct **my_arr=malloc(10 * structsz);
  int i;
  printf("Before\n");
  for (i = 0; i < 10; i++){
    my_arr[i]=malloc(structsz);
    my_arr[i]->a=20+i;
    my_arr[i]->b=10+i;
    printf("i=%d  a=%d, b=%d\n",i,my_arr[i]->a,my_arr[i]->b);
  }
  free(my_arr[9]);
  my_arr[9]=malloc(structsz);
  memcpy(my_arr[9], my_arr[1], structsz); //make 1st struct in array equal the 9th
  free(my_arr[8]);
  my_arr[8]=malloc(structsz);
  memcpy(my_arr[8], my_arr[2], structsz); //make 2st struct in array equal the 8th
  printf("After\n");
  for (i = 0; i < 10; ++i) {
    printf("i=%d  a=%d, b=%d\n",i,my_arr[i]->a,my_arr[i]->b);
    free(my_arr[i]);
  }
  free(my_arr);
  return 0;
}

The reason why the third parameter of memcpy must be the same as the size of the structure is because both pointers in memcpy are the type of struct.

If the 3rd parameter is too large, then you can run into segmentation faults because you could try to copy memory that you're not allowed to access, or at best, you could be modifying other structs in your program.

If the 3rd parameter is too small, then you could receive invalid or insufficient data.

Upvotes: 1

Related Questions