意外的内存值更改

时间:2018-01-22 15:15:48

标签: c free dynamic-memory-allocation

我是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,所以“如果&#39;条件成功,程序尝试释放未分配的内存。

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

1 个答案:

答案 0 :(得分:0)

经验法则 分配器功能(malloc()和系列)分配的空闲内存。

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

  

free函数导致ptr指向的空间被释放,即make   可供进一步分配。如果ptr是空指针,则不执行任何操作。否则,如果   该参数与先前由内存管理返回的指针不匹配   功能,或者如果通过调用freerealloc取消分配空间   行为未定义。

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

那就是语法

 if (string) {
      free(string);
 }

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