【问题标题】:Error while freeing a malloc'd pointer释放 malloc 的指针时出错
【发布时间】:2016-05-08 01:52:58
【问题描述】:

在以下代码中释放 malloc 的字符串时出现错误:

long authenticate(char* user, long* uid, long* gid){
FILE* fp = fopen("/etc/passwd", "r");
char * line = NULL;
size_t len = 0;
long lineSize;
char* uname;

if (fp == NULL)
  exit(EXIT_FAILURE);

  while ((lineSize = getline(&line, &len, fp)) != -1) {

    uname = (char*)malloc(lineSize*sizeof(char));
    getInfo(line, lineSize, &uname, &uid, &gid);

    if(strcmp(uname, user) == 0) {  // Strings are equal
      printf("we've found a user!\n");
      printf("uname: %s uid: %ld gid: %ld\n", uname, *uid, *gid);
      free(uname);
      exit(1);
    }

    free(uname);
  }
}

每当我找到一个有效的用户名,免费uname 然后退出什么都没有发生。但是,当我在循环结束时尝试释放 uname 时找不到有效的 uname(如果语句未得到评估),我会收到以下错误:

malloc: *** 对象 0x10d20ef2c 错误:未分配指针被释放

我不明白为什么 free() 没有注册 uname 以前是 malloc 的。鉴于错误的性质,我认为问题在于我不了解malloc/free

【问题讨论】:

  • 使用gcc -Wall -Wextra -g 编译您的代码,然后使用gdbvalgrind 对其进行调试。 BTW uname 是一个 POSIX 函数,所以最好使用其他名称。
  • Off-by-one: getline() 返回缓冲区中的字符数不包括终止'\0'。您的 malloc'ed 缓冲区太小。其余的可能只是 UB 的结果。
  • 感谢您对名称的提醒。当我使用 gdb 逐步完成它时,我在 strcmp 上得到一个段错误:(
  • 我不确定getInfo 在内部做什么,但很可能,它可能正在调整uname 的值(即更改通过uname++ 存储的地址,例如示例)。
  • @dhke getline() 实际上占了额外的字符

标签: c pointers memory-management malloc free


【解决方案1】:

问题很可能是getInfo() 修改了uname 指向的位置,之后free() 无法识别它。

【讨论】:

  • 你说得对,在 getInfo() 中我有一个相等的语句而不是 strncpy()。如果我有,可能是字符串的分配方式不同,比如: char* str = malloc(...); strncpy(str, otherStr, i);或 char* str = malloc(...); str = "某事";
  • @tonocom 对不起,我不明白这个问题。改写?
  • @tonocm char* str = malloc(...); str = "something"; 会完全清除您刚刚分配给str 的内存地址。相反,您要做的是将数据放入由str 指向的分配内存中,这是由strcpy(str,"something"); 完成的
猜你喜欢
  • 2017-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-08
相关资源
最近更新 更多