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

时间:2015-10-23 04:58:27

标签: c pointers memory-management struct

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

我在下面编写了一个测试程序,但是由于我对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 个答案:

答案 0 :(得分:1)

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

这是问题所在,您首先free(my_arr[0])然后将my_arr[1]复制到其指向的地址。

释放后不应该访问内存。 并在manpage

中指定
  

[...]内存区域不得重叠。如果是,请使用memmove          记忆区域确实重叠。

再次你这样做 -

   my_arr[9] = (struct my_struct *) malloc(sizeof(struct my_struct *));
因此,失去对它指向的前一个内存块的引用。

答案 1 :(得分:1)

此代码有效,我稍微清理了一下:

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

memcpy的第三个参数必须与结构的大小相同的原因是因为memcpy中的两个指针都是struct的类型。

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

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