C:内存分配问题
C: Memory allocation issues
我在 C 中遇到了(我认为)内存重新分配的问题。该程序旨在 运行 这样当 fopen(array, &num);
被调用时,它将首先检索元素的数量在文件中的数组中并将其放入 num 中,为给定的数组指针重新分配内存,为其提供足够的空间来存储文件本身的内容,然后将值复制到该数组中。这似乎在 fopen 函数中仍然有效(如 'mark 1' 所示),但在函数之外不起作用(如 'mark 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 00 00 00 00 01 02 03 04 01 02 06 0 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 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
改变了 num
取值成功。
但是 array
呢?好吧,您在 Rtest
上声明了它并在内存中为其分配了 space,这完全正确。然后,您想将它作为指针发送到 Rtest
,以便函数可以更改它。
array
是“指向结构个体的指针”类型的变量。这没关系,但如果您想在 Rtest
内更改它,那么您需要为该变量发送一个指针。因此,您需要一个“指向结构个体的指针”。请注意,变量名称是从之前复制的,我只是添加了“POINTER TO”
我相信你知道什么是指向指针的指针,你需要做的就是使用:
openf(&array, &num);
当然还有 modift 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
时,我得到以下输出:
53
Carlson
Carlson
Carlson
3
Carlson
Carlson
Carlson
编辑:
正如@WhozCraig 在评论中提到的,您可以使用函数的未使用 return 值和“新”数组的指针 return,这可能是一种更好的处理方式,而不是“指向指针的指针”的东西,但这取决于你。
我在 C 中遇到了(我认为)内存重新分配的问题。该程序旨在 运行 这样当 fopen(array, &num);
被调用时,它将首先检索元素的数量在文件中的数组中并将其放入 num 中,为给定的数组指针重新分配内存,为其提供足够的空间来存储文件本身的内容,然后将值复制到该数组中。这似乎在 fopen 函数中仍然有效(如 'mark 1' 所示),但在函数之外不起作用(如 'mark 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 00 00 00 00 01 02 03 04 01 02 06 0 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 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
改变了 num
取值成功。
但是 array
呢?好吧,您在 Rtest
上声明了它并在内存中为其分配了 space,这完全正确。然后,您想将它作为指针发送到 Rtest
,以便函数可以更改它。
array
是“指向结构个体的指针”类型的变量。这没关系,但如果您想在 Rtest
内更改它,那么您需要为该变量发送一个指针。因此,您需要一个“指向结构个体的指针”。请注意,变量名称是从之前复制的,我只是添加了“POINTER TO”
我相信你知道什么是指向指针的指针,你需要做的就是使用:
openf(&array, &num);
当然还有 modift 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
时,我得到以下输出:
53
Carlson
Carlson
Carlson
3
Carlson
Carlson
Carlson
编辑: 正如@WhozCraig 在评论中提到的,您可以使用函数的未使用 return 值和“新”数组的指针 return,这可能是一种更好的处理方式,而不是“指向指针的指针”的东西,但这取决于你。