Reputation: 688
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
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
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