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.Freitas
struct 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 */