简体   繁体   中英

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);
}
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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM