【问题标题】:Retaining C memory throughout the function在整个函数中保留 C 内存
【发布时间】:2010-10-27 06:52:57
【问题描述】:

假设我有一段类似这样的代码:

SOMESTRUCTURE *info;
info = malloc(sizeof(SOMESTRUCTURE));

while(something...)
{
     info->mini[0] = malloc(sizeof(SOMESTRUCTURE *)); // It's a structure inside the same structure
     while(something...)
     {
           info->mini[x]->name = malloc(sizeof(char *)*strlen(name));
           printf("%s\n", info->mini[0]->name); // This prints out the correct value
     }
}

printf("%s\n", info->mini[0]->name); // But now the value is lost and is null

如何使 info->mini[0]->name 值适用于整个函数?

【问题讨论】:

  • 这很乱。给出一些合适的代码。
  • 看到这里的malloc(sizeof(char *)*n),其他人的钟声不会响吗?

标签: c memory allocation


【解决方案1】:

不,您应该仍然可以使用它。唯一可能丢失该值的方法是 xwhile 循环的其中一次迭代中为 0,或者如果您在外循环内执行 malloc 而不进入内循环 - 很难判断是否这是可能的,因为在这两种情况下您都没有指定 something 是什么。

确实,在某个范围内创建的变量会在您退出该范围时消失,但这里不是这种情况。分配的内存将在范围更改后继续存在。在这种情况下,指向该内存的给定 指针 可能不是您的指针(当您退出外部 while 语句时,info 仍在作用域内)。

我确实看到了另一个潜在问题 - 您的 malloc(sizeof(char *) * strlen(name)) 可能应该是 malloc(strlen(name) + 1)(因为 sizeof(char) 始终为 1)。它可能会起作用,因为 char * 通常会比 char 大,但它仍然是错误的做法。

但是,我在你的代码中看不到任何地方设置 info->mini[0]->name 到任何东西,所以我不知道它如何能有一个正确的值,除非它以某种方式选择从之前的malloc 中增加一个值(这是可能的,因为malloc 本身不需要清除它给你的内存)。

您应该发布您的实际代码,或者最好是出现问题的最小代码段。

【讨论】:

  • 名称 buf 是在循环内分配的,因此 x 在某些阶段必须为零。他的代码过于混乱和不完整,无法做出任何有价值的假设。
  • 仅使用malloc(strlen(name) + 1) 是我所知道的用于动态分配字符串的唯一合理习惯用法...
【解决方案2】:

确保 x 永远不会是 0

【讨论】:

    【解决方案3】:

    我建议你使用 glib 的 g_strdup 函数,参见 API - 你会在 glib 中找到许多有用的函数来处理字符串:

    所以在你的情况下复制字符串name你只是这样做......

    info->mini[x]->name = g_strdup(name);
    

    已编辑 正如评论...您可以使用标准 strdup 来获得相同的功能:

    info->mini[x]->name = strdup(name);
    

    完结版

    通过这样做,info->mini[x]->name 将指向一个动态分配的内存空间,该空间将在您的函数之外可用 - 除非您释放它。

    如果你不想使用 glib 那么:

    info->mini[x]->name = malloc(sizeof(char) * (strlen(name) + 1));
    strcpy(info->mini[x]->name,name);
    

    在这种情况下,请注意 malloc 属于 sizeof(char),因为字符串是一个字符数组,而不是之前的 char *+1 是为空终止字符保存最后一个字符。

    【讨论】:

    • 或者,由于大量的 C 实现 strdup(),请改用它。或者,如果您的实现没有,只需编写一个 (stackoverflow.com/questions/252782/strdup-what-does-it-do-in-c/…),而不必费心尝试合并 glib。使用 glib 有很多很好的理由,像 strdup 这样无聊的小东西不是其中之一:-)
    • 当然@paxdiablo,我的意思是glib中有很多有用的函数来处理字符串。但是,我同意你的观点,glib 中还有许多其他功能使它成为一个非常有用的库。编辑答案以表明仅使用普通 strdup 也是一个不错的选择。并为您的 cmets +1。干杯。
    【解决方案4】:

    我看到你分配了info->mini[x]->name,然后在下一行打印出来。

    在这两者之间,您似乎没有真正将任何数据放入->name,所以我看不出它如何打印出正确的值。

    您分配的->name 取决于当时x 的值。但是你从来没有向我们展示过 x 被声明,或者它的值被设置。

    请告诉我们有关x 的声明和分配以及数据实际复制到->name 的位置的信息。

    【讨论】:

      猜你喜欢
      • 2010-11-18
      • 2013-08-13
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 2019-01-01
      • 2010-12-12
      • 2013-10-21
      相关资源
      最近更新 更多