2

我正在处理一些遗留代码,我必须在 cpp 文件中进行一些更改。cpp 文件包含外部“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) 我可以以以下 2 种形式返回 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).

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

4

2 回答 2

1

问题是返回一个char *. 当你使用 C++ 时,你不应该使用这种类型。这不是C!std::string或者std::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 的用户了解预期的内容。

于 2018-06-08T17:54:34.657 回答
0

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

于 2018-06-08T18:31:51.957 回答