将char **转换为char *或char

时间:2009-03-09 04:27:10

标签: c pointers char c-strings

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

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

* string = newstrdup(“有些字符串在这里”);

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

他在这个名为“newstrdup”的函数中做了什么? 我尝试了很多东西,但我不知道他在做什么......任何人都可以帮忙

6 个答案:

答案 0 :(得分: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时,应该注意有关行为的另一个注意事项。取决于您的图书馆可能允许或可能不允许。因此,如有必要,将适当的检查插入上述功能。在POSIX系统中有一个名为strdup的函数,但该函数既不允许NULL参数,也不使用C++运算符new来分配内存。

无论如何,我已经看了谷歌代码搜索newstrdup函数,发现了不少。也许你的图书馆是结果之一:

Google CodeSearch, newstrdup

答案 1 :(得分:3)

必须有一个原因,他们写了一个“新”版本的strdup。所以必须有一个角落案例,它处理不同。也许一个空字符串返回一个空字符串。

litb的回答是strdup的替代,但我认为他们做了他们所做的事情是有原因的。

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

答案 2 :(得分:1)

*string = newstrdup("Some string goes here");行没有向newstrdup显示任何奇怪之处。如果string的类型为char **,那么newstrdup只会按预期返回char *。据推测,string已设置为指向要放置结果的char *类型的变量。否则代码正在通过未初始化的指针写入..

答案 3 :(得分:0)

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

答案 4 :(得分: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;
}

当然,我应该保存* s1的副本并在realloc()失败时恢复它,但我不需要那个偏执狂。

答案 5 :(得分:0)

我认为您需要查看代码中“string”变量的情况,因为newstrdup()函数的原型看起来与库strdup()版本相同。

代码中是否有任何免费(*字符串)调用?

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

再次,我会问为什么?