我正在处理一些遗留代码,我必须在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).
哪一个是更好的解决方案?
答案 0 :(得分: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的用户理解预期的内容。
答案 1 :(得分:0)
确实应该返回string
,但如果你绝对需要返回char*
,那么第一种方法会更好。不要忘记free
。否则,strcmp(f(pt1), f(pt2))
之类的表达式将返回不可预测的结果。