插入和操作结构指针的动态数组

时间:2022-09-06 11:18:57

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.

这是我想要做的:1。创建一个struct指针数组。 2.使用malloc'd结构填充数组。 3.然后用新的malloc结构替换数组中的一个元素4.没有内存泄漏。

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?

我在下面编写了一个测试程序,但由于对memcpy的调用无效读写,我得到了seg错误。我究竟做错了什么?

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

2 个解决方案

#1


1  

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 .

这是问题,你先免费(my_arr [0]),然后在它指向的地址复制my_arr [1]。

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.

[...]内存区域不得重叠。如果内存区域重叠,请使用memmove。

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 .

因此,失去对它所指向的先前存储器块的引用。

#2


1  

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.

memcpy的第三个参数必须与结构的大小相同的原因是因为memcpy中的两个指针都是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.

如果第3个参数太大,那么您可能会遇到分段错误,因为您可能会尝试复制您不允许访问的内存,或者最多可以修改程序中的其他结构。

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

如果第3个参数太小,则可能会收到无效或不足的数据。

#1


1  

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 .

这是问题,你先免费(my_arr [0]),然后在它指向的地址复制my_arr [1]。

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.

[...]内存区域不得重叠。如果内存区域重叠,请使用memmove。

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 .

因此,失去对它所指向的先前存储器块的引用。

#2


1  

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.

memcpy的第三个参数必须与结构的大小相同的原因是因为memcpy中的两个指针都是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.

如果第3个参数太大,那么您可能会遇到分段错误,因为您可能会尝试复制您不允许访问的内存,或者最多可以修改程序中的其他结构。

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

如果第3个参数太小,则可能会收到无效或不足的数据。