将字符串转换为char *

时间:2012-02-23 12:44:24

标签: c++ static const

我正在尝试编写一个函数来将std :: string转换为char *。 我写的第一个是:

char* $ (string str)
{
    char* cstr;
    const unsigned int length=str.size();
    cstr=new char[1000];
    for(int i=0;i<length;i++)
        cstr[i]=str[i];
    cstr[length]=0;
    return cstr;
}

但问题是内存泄漏:让我们假设我这样做:

char* cstr;
string str1("hello"),str2("hello2");
cstr=$(str1);
cstr=$(str2);

在这种情况下存在内存泄漏。第一个分配的字符串不可访问但它的引用丢失。 所以我使用静态做了同样的事情:

char* $ (string str)
{
    static char cstr[1000];
    const unsigned int length=str.size();
    for(int i=0;i<length;i++)
        cstr[i]=str[i];
    cstr[length]=0;
    return cstr;
}

但现在问题是可以访问静态字段:

char* cstr;
string str("hello");
cstr=$(str);
$(str)[5]='!';

这是可能的,第6个字符被修改,因此cstr指向的C风格字符串也被修改。

使用const:

const char* $ (string str)
{
    static char cstr[1000];
    const unsigned int length=str.size();
    for(int i=0;i<length;i++)
        cstr[i]=str[i];
    cstr[length]=0;
    return cstr;
}

问题是char指针与const char指针不兼容,所以我不能这样做:

string str("hello");
char* cstr;
cstr=$(str);

但我只能使用const char指针。 我要做的是有一个函数,返回值只能作为右操作数,但不能作为赋值的左操作数。如何做到这一点?

我试着这样做:

char* toCharArray(string& str)
{
    std::unique_ptr<char>p(new char[1000]);
    char* temp=p.get();
    for(unsigned int i=0;i<str.size();i++)
    {
        *temp=str[i];
        temp++;
    }
    return p.get();
}

但问题仍然存在,我没有看到这个与我使用static发布的其他解决方案之间的区别。因为这样的代码:

char* cstr;
string str("hello");
cstr=toCharArray(str);
toCharArray(str)[0]='o';
cout << cstr;

修改字符串(打印“oello”)。 问题仍未解决。

5 个答案:

答案 0 :(得分:2)

您可以将分配的数组作为std::unique_ptr<char[]>std::vector<char>返回,以防止内存泄漏;如果重新分配或超出范围,两者都将释放内存。

您可以分别获得指向char*ptr.get()内容的&vec[0]指针。

顺便说一下,由于长度已知,因此数组长度确实应为length+1,而不是1000。固定大小的缓冲区是等待发生的溢出。此外,$不是函数的可移植名称。

答案 1 :(得分:1)

您需要创建一个新的char *并将std::string的内容复制到其上。

您可以使用strcpy

答案 2 :(得分:1)

http://www.cplusplus.com/reference/string/string/c_str/

看一下这个例子,具体来说:

char * cstr, *p;

string str ("Please split this phrase into tokens");

cstr = new char [str.size()+1];
strcpy (cstr, str.c_str());

答案 3 :(得分:0)

我不明白为什么你对内存泄漏感到惊讶。如果你要复制一些东西,你必须把它放在某个地方。

您可以将所有副本放在同一个地方(冒着溢出的风险,并承担在客户端上获取正确副本的责任,或者他们冒着意外损坏的风险),或者您进行分配(他们仍然需要进行释放,但至少他们不需要复制),或者让他们将缓冲区和大小传递给你的函数。

严肃地说,$作为一个函数名?

答案 4 :(得分:-3)

str.c_str()怎么样?或strdup(str.c_str())如果您想要副本。