使用String c_str()返回char *

时间:2018-06-08 17:20:23

标签: c++ c-strings c-str

我正在处理一些遗留代码,我必须在cpp文件中进行一些更改.cpp文件包含extern“c”块中的完整代码 -

我更新了一个返回char *的函数。代码看起来像下面的func1()。 由于我使用std :: strring和stringstream,我在extern块之前包含了sstream和string头文件。 从c和cpp文件调用下面的函数。所以我不能在这里返回std :: string -

char* func1(someStruct* pt){
    std::strig nam = somefunc(pt);
    //have to append some integer in particular format
    std::stringstream ss;
    ss<<nam<<pt->int1 ......;

    nam = ss.str(); 
    //More code here for returning char* based on queries - (a)
}

在其中一个调用此函数的地方 -

void otherFunc(.....){
    //......
    char* x = func(myptr);
    if(based_on_some_condition){
        char* temp = func3(x); //returns a char* to dynamically allocated array.
        strcpy(x,temp);       //copying (b)

    }
    //..........
}

以下是我的询问 -
1)在(a)我可以用以下两种形式返回char *。我必须作出决定,以便在(b)处复制不会导致任何未定义的行为 -

i)Create a char array dynamically with size = nam.length()+10 (extra 10 for some work happening in func3).<br>
    char* rtvalue = (char*)calloc(sizeof(char),nam.length()+10);
    strcpy(rtvalue,nam.c_str());
    return rtvalue;
    And free(temp); in otherFunc() after strcpy(x,temp);

ii) Declare 'nam' as static std::string nam;
    and simply return const_cast<char*>(nam.c_str());
    Will defining 'nam' with static scope ensure that a correct return happen from function (ie no dangling pointer at 'x')?
    More importantly, can I do this without worrying about modification happening at (b).

哪一个是更好的解决方案?

2 个答案:

答案 0 :(得分:1)

问题是返回char *。使用C ++时,不应使用此类型。这不是C!应该使用std::stringstd::vector<char>

如果在这种函数中使用char *作为返回类型,它将以未定义的行为(访问已释放的内存)或内存泄漏结束。

如果您将使用static std::string nam;功能将保持内部状态,这总是会导致麻烦。 例如,如果您创建线程功能,您将具有未定义的行为。更糟糕的是,如果你因为某种原因两次使用这个功能,第二次通话的结果将对第一次通话的结果产生影响(例如你的同事将使用这个功能,因为他不会期望隐藏的副作用)。

如果您正在设计一些应该可以从C代码访问的API,那么您应该以不同的方式设计此API。我不知道你提供什么样的功能,可能你应该这样:

char *func1(someStruct* pt, char *result, int size){ // good name could be like this: appendStructDescription
    std::strig nam = somefunc(pt);
    //have to append some integer in particular format
    std::stringstream ss;
    ss<<nam<<pt->int1 ......;

    nam = ss.str(); 

    int resultSize = std::min(size - 1, nam.length());
    memcpy(result, nam.c_str(), resultSize);
    result[resultSize] = 0;
    return result + resultSize;
}

这种方法有很大的优势:内存管理的责任在于调用者,API的用户理解预期的内容。

答案 1 :(得分:0)

确实应该返回string,但如果你绝对需要返回char*,那么第一种方法会更好。不要忘记free。否则,strcmp(f(pt1), f(pt2))之类的表达式将返回不可预测的结果。