我正在查看以下代码(简化了),并问自己使用此returnMsg
功能的安全性:
#include <iostream>
using namespace std;
const char *returnMsg(const char *msg)
{
static std::string message;
message = msg;
return message.c_str();
}
int main(int argc, char *argv[])
{
const char *msg1 = returnMsg("Hello world");
printf("msg1 = %p\n", msg1);
cout << msg1 << endl;
const char *msg2 = returnMsg("Good bye");
printf("msg2 = %p\n", msg2);
cout << msg2 << endl;
cout << msg1 << endl;
return 0;
}
输出为:
msg1 = 0x23a6028
Hello world
msg2 = 0x23a6028
Good bye
Good bye
msg2
两次写入,这是我期望的,因为静态消息变量在程序有效期内仍保留在内存中,并且没有内存重新分配,因此在msg1
address处写入的内容将由的新内容替换msg2
。
但是,如果的大小msg2
较大,则std::string message
变量内部将进行内部重新分配,并且输出为:
msg1 = 0x1cc6028
Hello world
msg2 = 0x1cc6058
Good bye looooooooooooooooooooooooooooooooooooooooong
Hello world
但是我猜不能保证msg1
地址将来不会被重用,因此对msg1
内容的新访问可能最终会显示出不同且不一致的内容。
是否需要以不同的方式编写此函数才能使其不受上面显示的限制使用?
从内部使用静态std :: string的函数返回const char *是否安全?
是的,那很安全。
但是,在指针无效后再使用该指针是不安全的,这就是所示程序的作用。如果重新分配了指针,则在连续调用该函数时,该指针会使该指针无效。因此,指针仅在下一次调用该函数之前才是安全的(这将导致重新分配)。
是否需要以不同的方式编写此函数才能使其不受上面显示的限制使用?
该功能具有所描述的限制,因此当然必须以不同的方式编写以不具有那些限制。
该方法的核心问题是,您只有一个静态字符串,但是要存储多个字符串,同时又不丢弃任何较早的字符串。因此,似乎您需要一堆静态字符串:
const char *returnMsg(const char *msg)
{
static std::forward_list<std::string> messages;
messages.emplace_front(msg);
return messages.front().c_str();
}
尽管这可以按您期望的那样工作,但它很愚蠢。考虑您是否真的要在其余的执行中存储所有字符串。如果不是,则静态存储不是解决方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句