C 调用函数并将另一个结构作为参数传递后,结构的元素将丢失其值
我有一个我想不出来的问题。我有以下文件:C 调用函数并将另一个结构作为参数传递后,结构的元素将丢失其值,c,pointers,struct,C,Pointers,Struct,我有一个我想不出来的问题。我有以下文件:file\u reader.c、file\u reader.h、file\u writer.c、file\u writer.h、test\u file\u reader.c 我正在使用“struct”来读写文件。为了更好地理解,我编写了以下代码test\u file\u reader.c: #include <stdio.h> #include "file_reader.h" #include "file_writer.h" int main
file\u reader.c、file\u reader.h、file\u writer.c、file\u writer.h、test\u file\u reader.c
我正在使用“struct”来读写文件。为了更好地理解,我编写了以下代码test\u file\u reader.c
:
#include <stdio.h>
#include "file_reader.h"
#include "file_writer.h"
int main ()
{
char *file_path = "/home/freitas/Dropbox/projects/gcleaner/cleaners/custom.xml";
struct FileReader *fr = malloc(sizeof(struct FileReader));
file_reader_new (file_path, fr);
show_file_reader_values(fr);
struct FileWriter *fw = malloc(sizeof(struct FileWriter));
fw->file_path = "/tmp/text1.txt";
fw->content = "aaa";
write (fw);
show_file_reader_values(fr);
return 0;
}
void show_file_reader_values(const struct FileReader *fr)
{
printf("==========FILE READER==========\n");
printf("file path: %s\n", fr->file_path);
printf("----------file content---------\n");
printf("content:\n%s\n", fr->content);
printf("----------file content---------\n");
printf("n lines: %d\n", fr->n_lines);
printf("n characters: %d\n", fr->n_characters);
printf("==========FILE READER==========\n\n");
}
文件\u writer.c
#include <stdio.h>
#include "file_writer.h"
void write (struct FileWriter *fw)
{
FILE *f = fopen(fw->file_path, "w");
if (f == NULL)
{
printf("Error opening file!\n");
exit(1);
}
fprintf(f, "%s", fw->content);
fclose(f);
}
你能帮我吗?谢谢
struct FileReader *fr = malloc(sizeof(struct FileReader));
没有必要这样做。您所需要的就是:
struct FileReader fr;
这里也一样:
struct FileWriter fw;
然后将这些变量的地址传递给必要的函数
注意,这并不是作为一个答案提供给您的,只是作为一个注释来清理代码,以删除对堆的无关调用。碰巧,真正的问题存在于其他地方,而您在这里看到的是
未定义的行为
。我不确定您是如何从文件中逐个字符或块读取的,但无论如何
由于更新content
buffer中读取的数据,并将content
buffer的地址存储在file\u reader\u new()
变量fr->content
中,并且立即释放内存将导致读取的数据丢失。并导致名为“悬挂指针”的条件
悬空指针
(指向已释放内存的指针变量)
这就是为什么总是建议在释放到NULL
后设置指针变量的原因。在某些情况下,取消对悬挂指针的引用将导致分段错误
或未定义行为
另外,由于struct
的所有成员变量都是指针,因此最好将它们初始化为NULL
如果使用动态分配,可以使用
calloc
初始化struct
中的所有变量,而不是使用malloc
将所有成员初始化为NULL
。这也适用于string
。我看到了一个问题:
fr->content = content;
fr->n_lines = counter;
fr->n_characters = i;
/* Clean up. */
free(content); /* <-- Danger */
由于您对内容调用了free()
,该指针不再指向有效内存,因此会发生未定义的行为
解决方法是在fr
上为内容分配空间,并将content
的字符复制到此空间,或者干脆不调用content
上的free
因此,要么这样做:
fr->content = malloc(i + 1);
strcpy(fr->content, content);
fr->n_lines = counter;
fr->n_characters = i;
/* Clean up. */
free(content);
或者这个:
fr->content = content;
fr->n_lines = counter;
fr->n_characters = i;
/* No call to free(content) done */
请显示结构定义,以及
文件读取器\u new
函数。我猜您正在返回/存储堆栈的地址variable@ViníciusM.Freitasstruct FileReader*fr=malloc(sizeof(struct FileReader))代码>没有必要这样做。您所需要的就是:struct FileReader fr代码>此处相同:struct FileWriter fw代码>。然后只需将这些变量的地址传递给必要的函数即可。@PaulMcKenzie你说得对!只需声明结构,然后将其内存位置传递给函数即可!。非常感谢你。我想知道到底发生了什么。你知道吗?@ViníciusM.Freitas-现在还不要太高兴。这可能是一个内存覆盖错误,而且该错误仍然存在。我们需要查看您正在使用的数据示例。我建议您稍微整理一下代码。这可能不是程序的问题所在。是的,您进入堆的次数减少了,但这可能掩盖了现有的bug。
struct FileReader *fr = malloc(sizeof(struct FileReader));
struct FileReader fr;
struct FileWriter fw;
fr->content = content;
fr->n_lines = counter;
fr->n_characters = i;
/* Clean up. */
free(content); /* <-- Danger */
printf("content:\n%s\n", fr->content);
fr->content = malloc(i + 1);
strcpy(fr->content, content);
fr->n_lines = counter;
fr->n_characters = i;
/* Clean up. */
free(content);
fr->content = content;
fr->n_lines = counter;
fr->n_characters = i;
/* No call to free(content) done */