C:内存分配问题

问题描述

我在 C 中(我认为)内存重新分配有问题。该程序旨在运行,以便在调用 fopen(array,&num); 时,它将首先从文件中检索数组中的元素数,然后将其放在 num 中,为给定的数组指针重新分配内存,为其提供足够的空间来正确存储文件内容,然后将值复制到该数组中。这似乎在 fopen 函数中仍然有效(由“标记 1”显示),但在此之外不起作用(由“标记 2”显示),而似乎吐出随机内存垃圾。任何帮助表示赞赏(包括代码和格式化我布局不佳的问题)。

//main.c
void Rtest(){

  char num;
  struct individual *array;
  array = (struct individual *) malloc(sizeof(struct individual));

  openf(array,&num);

  printf("%d\n",num);

  for (int i = 0; i < num; i++) {printf("%s\n",array[i].name);} //mark 2

  free(array);

}
//fil.h
struct individual {
    char name[32];
    char stats[7];
    char role;
    char roles[13];
};

void openf(struct individual *array,char *num){

  FILE *fp;

  fp = fopen("save.bin","rb");
  fread(num,1,sizeof(char),fp);
  array = (struct individual *)realloc(array,*num * sizeof(struct individual));
  printf("%d\n",sizeof(*array));
  fread(array,*num,sizeof(struct individual),fp);
  for (int i = 0; i < *num; i++) {printf("%s\n",array[i].name);} //mark 1

  fclose(fp);

}

文件内容

03 43 61 72 6C 73 6F 6E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 06 07 08 09 0A 0B 0C 43 61 72 6C 73 6F 6E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 02 03 04 05 06 08 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 43 61 72 6C 73 6F 6E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 02 03 04 05 06 08 00 01 02 03 04 05 06 07 08 09 0A 0B 0C

解决方法

当你想改变函数内部的参数时,你传递一个指向它的指针。 例如,在 Rtest 中,您声明了一个名为 num 的字符。它没有值,您将其发送到 openf,但是您实际上将指针发送到 num,因为您想更改其值,您正确地进行了操作并且确实 openf 更改了 {{ 1}} 值成功。

但是num怎么样?好吧,您在 array 上声明了它并为它分配了内存空间,这是正确的。然后,您想将它作为指针发送给 Rtest,以便函数可以更改它。 Rtest 是“指向结构个体的指针”类型的变量。这没关系,但是如果您想在 array 内更改它,那么您需要发送该变量的指针..因此,您需要一个“指向个人结构的指针”。请注意,变量名是从之前复制的,我只是添加了“POINTER TO”

我相信你知道什么是指向指针的指针,你需要做的是使用:

Rtest

当然还有修改 openf(&array,&num); 以便它使用新的“指向指针的指针”,类似这样:

openf

当我在我的机器上运行此代码以及 void openf(struct individual **array,char *num){ FILE *fp; fp = fopen("save.bin","rb"); fread(num,1,sizeof(char),fp); *array = (struct individual **)realloc(*array,*num * sizeof(struct individual)); printf("%d\n",sizeof(**array)); fread(*array,*num,sizeof(struct individual),fp); for (int i = 0; i < *num; i++) {printf("%s\n",(*array)[i].name);} //mark 1 fclose(fp); } 并提供 Rtest 时,我得到以下输出:

save.bin

编辑: 正如@WhozCraig 在评论中提到的,您可以使用函数未使用的返回值并返回“新”数组的指针,这可能是一种更好的处理方式,而不是“指向指针的指针”的东西,但这取决于你。