1

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

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

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

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

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

4

6 回答 6

4

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

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

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. 取决于您的图书馆,可能允许或不允许。因此,如有必要,请在上述函数中插入适当的检查。strdup在 POSIX 系统中有一个名为 available 的函数,但该函数既NULL不允许参数,也不允许使用C++operator new 来分配内存。

无论如何,我已经用谷歌代码搜索newstrdup功能找到了很多。也许您的图书馆是其中的结果:

谷歌代码搜索,newstrdup

于 2009-03-09T04:36:53.290 回答
3

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

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

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

于 2009-03-09T04:59:37.747 回答
1

这条线*string = newstrdup("Some string goes here");没有表现出任何奇怪newstrdup。如果string有类型char **,则newstrdup只是char *按预期返回。大概string已经设置为指向char *要放置结果的类型的变量。否则代码正在通过未初始化的指针写入..

于 2010-06-27T13:50:18.713 回答
0

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

于 2009-03-09T04:33:27.277 回答
0

看起来他编写了一个 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 的副本并恢复它,但我不需要那么偏执。

于 2009-03-09T04:35:16.027 回答
0

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

代码中是否有任何 free(*string) 调用?

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

再次,我会问为什么?

于 2009-03-09T04:57:50.557 回答