【问题标题】:converting char** to char* or char将 char** 转换为 char* 或 char
【发布时间】:2010-10-12 02:52:39
【问题描述】:

我有一个旧程序,其中使用了一些库函数,但我没有那个库。

所以我正在使用 c++ 库编写该程序。 在那个旧代码中,有一些函数是这样调用的

*string = newstrdup("这里有一些字符串");

字符串变量被声明为 char **string;

他可能在那个名为“newstrdup”的函数中做什么? 我尝试了很多东西,但我不知道他在做什么......谁能帮忙

【问题讨论】:

  • 能贴一下newstrdup()函数吗?
  • @tinkertim:“我有一个旧程序,其中使用了一些库函数,但我没有那个库”...
  • 你能在使用 newstrdup 的地方粘贴任何旧代码吗?最好在循环内。您是否有来自 .h 文件的 newstrdup 声明?
  • 还有一个:这个库中还有其他newstrXXXXX函数吗?如果是这样,它们是否符合它们的 stdlib 函数?例如,newstrpos 或 newstrcmp?

标签: c pointers char c-strings


【解决方案1】:

该函数用于制作 c 字符串的副本。这通常是获取字符串文字的可写版本所必需的。它们(字符串文字)本身是不可写的,因此这样的函数将它们复制到分配的可写缓冲区中。然后,您可以将它们传递给修改给定参数的函数,例如strtok,它写入它必须标记的字符串。

我认为你可以想出这样的东西,因为它被称为 newstrdup:

char * newstrdup(char const* str) {
    char *c = new char[std::strlen(str) + 1];
    std::strcpy(c, str);
    return c;
}

你应该在使用字符串完成后释放它

delete[] *string;

另一种编写方式是使用malloc。如果库是旧的,它可能已经使用了 C++ 从 C 继承的那个:

char * newstrdup(char const* str) {
    char *c = (char*) malloc(std::strlen(str) + 1);
    if(c != NULL) {
        std::strcpy(c, str);
    }
    return c;
}

现在,您应该在完成后使用free 释放字符串:

free(*string);

如果您使用 C++ 编写,请首选第一个版本。但如果现有代码使用free 再次释放内存,请使用第二个版本。请注意,如果没有内存可用于复制字符串,则第二个版本返回 NULL,而在这种情况下,第一个版本会引发异常。当您将NULL 参数传递给newstrdup 时,应注意有关行为。取决于您的图书馆,可能允许或不允许。因此,如有必要,请在上述函数中插入适当的检查。在 POSIX 系统中有一个名为 strdup 的函数,但该函数既不允许 NULL 参数,也不允许使用 C++ 运算符 new 来分配内存。

不管怎样,我用谷歌代码搜索了newstrdup 函数,发现了很多。也许你的图书馆就是其中之一:

Google CodeSearch, newstrdup

【讨论】:

  • 我尝试过这样的程序。我这样称呼newstrdup。 *ersponse = newstrdup(buffer) where buffer ="chaithra" 但在运行时它作为分段错误给出。
  • 那么我认为您应该添加一个空检查:如果 str 为 NULL,则立即返回 NULL。因为第二个版本和 POSIX strdup 版本之间的唯一显着区别是检查 null (当然,在名称旁边)。这将是他们提供自己的版本的一个很好的理由。
  • ok.thanks 它的工作如果我调用为 response = newstrdup("some string");其中 response 是 char* 但如果 response 是 char ** 并且如果我调用 *response=newstrdup("some string");这是分段错误。可能是我没有分配内存,谢谢
  • Chaithra,当然,你必须让你的指针指向某个地方。像 char *c;字符 **p = &c;然后你可以做 *p = newstrdup.... 只是做 char **p; *p = newstrdup... 将写入一些不确定的内存位置,如果幸运的话它会崩溃(或者如果你不幸运的话会默默地出错)
  • 如果您执行 char c = newstrdup... 则该功能可以正常工作。那么这个错误就是让 char* 指向某个合理的地方,当然。
【解决方案2】:

他们编写了一个“新”版本的 strdup 肯定是有原因的。所以必须有一个角落案例,它以不同的方式处理。就像一个空字符串可能会返回一个空字符串。

litb 的回答是 strdup 的替代品,但我认为他们这样做是有原因的。

如果您想直接使用 strdup,请使用定义来重命名它,而不是编写新代码。

【讨论】:

  • 是的,因为它被称为“new”strdup,我认为它使用 operator new 而不是 malloc(strdup 使用 malloc)。出于便携性的原因,它们也可能有自己的。我不知道:)
  • 它也可能被称为 newstrdup() 仅仅是因为 strdup() 不是标准的,尽管它被广泛使用,并且他们希望保持清晰。使用“newstrdup()”来表示“strdup-variant-using-new”也是合理的。
  • strdup() 内置函数没问题。但是当我使用 *response = newstrdup("Some String") 调用该函数时,我遇到了分段错误。这可能是什么原因以及如何克服?
  • 你能发布一个工作代码和你的测试用例的sn-p吗?没有更多的上下文,现在很难说。另外,你有编译过的库吗,因为反转它也是一种选择。
【解决方案3】:

*string = newstrdup("Some string goes here"); 行对newstrdup 没有任何奇怪之处。如果string 的类型为char **,那么newstrdup 只是按预期返回char *。大概string 已经设置为指向char * 类型的变量,结果将被放置在其中。否则代码是通过一个未初始化的指针写的..

【讨论】:

    【解决方案4】:

    newstrdup 可能正在创建一个与传递的字符串重复的新字符串;它返回一个指向字符串的指针(它本身就是一个指向字符的指针)。

    【讨论】:

    • 奇怪,为什么不直接返回一个指向字符的指针?
    • @Iraimbilanja:似乎是。
    【解决方案5】:

    看起来他编写了一个 strdup() 函数来操作现有指针,可能是将其重新分配到新的大小,然后填充其内容。很可能,他这样做是为了在循环中重复使用相同的指针,其中 *string 将频繁更改,同时防止每次后续调用 strdup() 时发生泄漏。

    我可能会像 string = redup(&string, "new contents") .. 那样实现它,但这只是我。

    编辑

    这是我的“redup”功能的一个片段,它可能与您发布的内容类似,只是方式不同:

    int redup(char **s1, const char *s2)
    {
        size_t len, size;
    
        if (s2 == NULL)
            return -1;
    
        len = strlen(s2);
        size = len + 1;
    
        *s1 = realloc(*s1, size);
    
        if (*s1 == NULL)
            return -1;
    
        memset(*s1, 0, size);
        memcpy(*s1, s2, len);
    
        return len;
    }
    

    当然,如果 realloc() 失败,我可能应该保存 *s1 的副本并恢复它,但我不需要那么偏执。

    【讨论】:

      【解决方案6】:

      我认为您需要查看代码中的“字符串”变量发生了什么,因为 newstrdup() 函数的原型似乎与库 strdup() 版本相同。

      代码中有free(*string)调用吗?

      这似乎是一件奇怪的事情,除非它在内部保留重复字符串的副本并再次返回指向同一字符串的指针。

      再次,我想问为什么?

      【讨论】:

      • 是的,我也在想同样的事情,必须有一些角落案例它的处理方式不同:)
      猜你喜欢
      • 2011-06-08
      • 1970-01-01
      • 2021-04-29
      • 2013-10-18
      • 2012-01-15
      • 2020-11-25
      • 1970-01-01
      • 1970-01-01
      • 2012-07-01
      相关资源
      最近更新 更多