我有以下函数:
MyFunction(const char *value, bool trigger) {
if (trigger) {
std::string temporaryString = getTemporaryStringFromSomewhereElse();
value = temporaryString.c_str();
}
// do processing here
// I need `value` and `temporaryString.c_str();` to be alive and accessible here and not destroyed
MyClass *object = new MyClass(value);
object->Work();
// etc..
}
所以,问题是,我怎样才能";延长";temporaryString
的生命周期是否在if
-子句的范围之外?
目前,我得到以下错误:
使用指向超出范围的局部变量"temporary"的指针。
我理解这与内存管理有关,并且假设temporary
是";销毁";或者在CCD_ 4-子句之后从存储器中清除。但我需要延长它的生命周期,或者创建另一个字符串(副本(,它将具有不同的、更广泛的范围。
我怎样才能做到这一点?
要求:
- 函数签名不能更改,应保留为:
MyFunction(const char *value, bool trigger)
- 稍后我使用
value
初始化另一个对象,做一些其他工作。我不能有两个变量,例如value
和anotherValueToBeUsedIfTriggerIsTrue
只需将std::string
的声明从if
块移到功能块中,例如:
MyFunction(const char *value, bool trigger) {
std::string temporaryString;
if (trigger) {
temporaryString = getTemporaryStringFromSomewhereElse();
value = temporaryString.c_str();
}
// do processing here
MyClass *object = new MyClass(value);
object->Work();
// etc..
}
std::string
最初将为空,并在函数退出时销毁,因此,只要temporaryString
未被修改,重新分配的value
将在函数运行期间保持有效。
静态存储可能就是您要搜索的。变量的static
属性将其生存时间扩展到整个程序执行时间。
void MyFunction(const char *value, bool trigger) {
if (trigger) {
static std::string s_buffer; // Note : this line is executed only once so don't assign the value here
s_buffer = getTemporaryStringFromSomewhereElse();
value = s_buffer.c_str();
}
// use of value is still correct even outside the if statement.
}
注意:在多线程程序的情况下,静态的使用不是线程安全的,对于这种情况,标准提供了thread_local存储。
在这种情况下,我更喜欢std::optional
,因为它还显示是否设置了请求的对象。
示例:
std::string getTemporaryStringFromSomewhereElse()
{
return "Here I am";
}
std::optional< std::string > MyFunction(bool trigger) {
if (trigger) {
return getTemporaryStringFromSomewhereElse();
}
return std::nullopt;
}
int main()
{
auto retval = MyFunction( true );
if ( retval )
{
std::cout << *retval << std::endl;
}
}
编辑:(在我们得到界面不可更改的信息后(
这最终导致了所有权问题!
谁将分配传递字符串的内存,谁负责释放该内存。
选项:
- 分配足够的空间,并将指向该内存的指针传递给函数,如果设置了触发器,则复制内容,或者将内存的第一个字符设置为零,以显示您传递回一个空字符串。如果也可以使用空字符串,则使用例如第一个或最后一个内存元素作为标志
- 分配函数内部的内存,复制给定的字符串并传回指针,如果未设置触发器,则返回nullptr。函数的调用方必须处理释放给定内存的问题
- 如果保证在第一次调用和内容使用之间不会再次调用函数,则函数本身可以保留一个静态数组,并将地址传回该静态内存
BTW:保留损坏的接口是坏软件的一个好的起点:-(在给定的情况下,如果空字符串也是有效的,你就开始用数组中的标志和所有损坏的东西进行黑客攻击(通常我们应该使用带有标志的structs,正如std::optional所定义的那样(。