【问题标题】:C Memory Overflow (v2)C 内存溢出 (v2)
【发布时间】:2010-10-27 12:56:51
【问题描述】:

编辑:使用新的 Pastebin 链接更新了代码,但它仍在 info->citizens[x]->name while 循环处停止。在循环中添加了 realloc 并整理了代码。任何更多的 cmets 将不胜感激

我遇到了一些内存分配溢出问题

http://pastebin.com/vukRGkq9 (v2)

无论我尝试什么,都没有为 info->citizens 分配足够的内存,而 gdb 经常说它无法访问 info->citizens[x]->name。

有时,我什至会在 strlen 的 printf 语句之后直接得到 KERN_INVALID_ADDRESS 错误(在 gdb 由于错误而停止的代码中没有使用 strlen,但我假设 printf 以某种方式使用 strlen) .我认为这与结构如何分配内存有关。所以我想知道是否有人可以看看?

【问题讨论】:

  • 您是否尝试过尽可能地缩小代码以便只显示有问题的行?对我们和您来说,调查会容易得多。
  • “更新代码”是什么意思?你的意思是你已经对你的问题做出了可怕的答案,因为它们现在指向不存在的行吗?哦,是的,确实如此,这两个版本的差异足以包含完全不同的错误集。嗯……

标签: c memory allocation


【解决方案1】:

您不应该这样做malloc(sizeof(PEOPLE*)),因为它为指针分配了确切的字节数(32 位拱门上的 4 个字节)。
似乎您想要做的是malloc(sizeof(PEOPLE) * N),其中 N 是最大值。您想放入该内存块的人数。

【讨论】:

    【解决方案2】:

    显然问题出在:

    info->citizens = malloc(sizeof(PEOPLE *));
    info->citizens[0] = malloc(sizeof(PEOPLE *));
    info->citizens[1] = malloc(sizeof(PEOPLE *));
    

    从逻辑上思考你在这里尝试做什么。

    【讨论】:

    • 我不同意,给出提示而不是完整答案是完全有效的,特别是如果问题(主观上)微不足道:)
    【解决方案3】:

    您的结构几乎可以肯定不包含以下成员:

    time_t *modtimes;
    mode_t *modes;
    bool *exists;
    

    您应该简单地使用:

    time_t modtimes;
    mode_t modes;
    bool exists;
    

    这样您就不需要动态分配它们,或者随后释放它们。原因是a)它们很小,b)它们的大小是事先知道的。你使用:

    char *name;
    

    对于字符串字段,因为它不小,而且你事先不知道它有多大。

    在代码的其他地方,您有以下内容:

    if(top)
    {
      PEOPLE *info;
      info = malloc(sizeof(PEOPLE *));
    }
    

    如果 top 为真,则此代码分配一个指针,然后立即泄漏它——第二个 info 的范围仅限于 if 语句,因此您既不能以后使用它,也不能以后释放它。你需要做这样的事情:

    PEOPLE *process(PEOPLE *info, ...)
    {
      if (top)
      {
        info = malloc(sizeof(PEOPLE));
      }
    
      info->name = strdup("Henry James");
      info->exists = true;
      return info;
    }
    

    【讨论】:

      【解决方案4】:

      您的间接级别似乎太多了。你为什么用**citizens而不是*?

      另外,除了你为指针而不是结构分配空间之外,还有一些奇怪的事情,例如第 31 行的局部变量 info 意味着初始分配超出范围一旦块在第 34 行关闭。

      您需要更清楚地考虑哪些数据在哪里。

      【讨论】:

        【解决方案5】:

        这段代码存在很多内存分配问题。上面提到的还有许多其他的,例如:

        info->citizens[masterX]->name = malloc(sizeof(char)*strlen(dp->d_name)+1);
        info->citizens[masterX]->name = dp->d_name;
        

        您不能通过赋值(使用 =)在 C 中复制字符串。你可以这样写:

        info->citizens[masterX]->name = malloc(strlen(dp->d_name)+1);
        strcpy(info->citizens[masterX]->name, dp->d_name);
        

        或者您可以将整个分配和复制压缩如下:

        info->citizens[masterX]->name = strdup(dp->d_name);
        

        在第 143/147 行类似(除非在这种情况下,您在 malloc 调用中也分配了一个太少的字节)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-14
          相关资源
          最近更新 更多