意外的内存值更改

Unexpected memory value change

我是 C 的新手,我创建了一个小结构:

typedef struct my_struct {
  union {
    char *string;
    char *filename;
  } x;
} my_struct_t;

我有这些函数来创建和释放 my_struct 个实例:

#include <stdlib.h>
#include <string.h>

my_struct_t *build_struct(){
  my_struct_t *obj;
  obj = malloc(sizeof(my_struct_t));
  obj->x.filename = NULL;
  obj->x.string   = NULL;
  return( obj );
}

void free_all(my_struct_t *obj){
  char *string = obj->x.string;
  char *filename = obj->x.filename;
  if (string) free(string);
  if (filename) free(filename);
  free(obj);
}

但是,当我无法成功使用它们时。这是我的测试程序:

void modify_struct(my_struct_t *obj, const char *value){
    char *temp = malloc(strlen(value));
    memcpy(temp,value,strlen(value));
    obj->x.filename = temp;
}

int main(){
  my_struct_t *obj = build_struct();
  modify_struct(obj,"invented string");
  free_all(obj);
  return 0;
}

我将 stringfilename 的结构设置动态分配给 NULL。然后我在释放内存之前更改 filename 的值。

在调用 free_all() 期间,似乎 string 不再是 NULL 所以两个 'if' 条件都成功,并且程序试图释放一个非-分配的内存。

为什么会发生这种情况,即使我从未接触过 string?我该如何解决?

经验法则:只有分配器函数分配的空闲内存( malloc() 和家人)。

引用 C11,章节 §7.22.3.3,(强调我的

The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

在您的情况下,您尝试释放 obj->x.filename,它是指向 字符串文字 的指针,分配器函数未返回。因此,将其传递给 free,您的代码将调用 undefined behavior.

也就是说,语法

 if (string) {
      free(string);
 }

没有多大意义,因为将 NULL 指针传递给 free() 是完全可以接受的。