我正在处理一些遗留代码,我必须在 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).
哪一个是更好的解决方案?
问题是返回
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 的用户了解期望的内容。
确实应该返回
string
,但如果你绝对需要返回char*
,第一种方法更好。别忘了free
。否则,像 strcmp(f(pt1), f(pt2))
这样的表达式将返回不可预测的结果。