[英]Segmentation fault when returning string from function in c++
我上课有错误。 我怀疑这很简单,也许我无法理解字符串在C ++中的工作方式。 我的函数尝试将本地std :: string返回到另一个std :: string,但是我没有得到字符串,而是在函数返回后遇到了段错误。 这是我的代码:
TestClass::TestClass(std::string a, std::string b)
{
m_a = a;
m_b = b;
}
std::string TestClass::stringHandler()
{
const char myTemplate[] = "a=%s,b=%s";
char formattedString[strlen(myTemplate) + m_a.length() + m_b.length()];
sprintf( formattedString, myTemplate, m_a.c_str(), m_b.c_str());
std::cout << "formattedString= " << formattedString << "\n";
std::string returnStr(formattedString);
std::cout << "returnStr=" << returnStr << "\n";
return returnStr;
}
int main(...)
{
/* getting a and b from argv */
TestClass MyClassObj(a, b);
std::string strRet = MyClassObj.stringHandler();
std::cout << "Back after stringHandler\n";
return 0
}
在stringHandler中,当我打印returnStr时,它将正确显示。 但是在那之后,我遇到了Segmentation错误,并且没有打印出“在stringHandler之后返回”。 你们有主人吗,知道我在做什么错吗?
几个问题:
%b
不是有效的格式说明符。 %b
是固定的!),但是您仅传递了2个参数。 formattedString
分配足够的内存。 (更新:)对OP进行编辑后,其中的前三个已修复,因此,如果您的编译器还具有运行时数组大小的扩展名,则此代码不会导致segfault。
最简单的解决方法是编写:
std::string returnStr = "a=" + m_a + ",b=" + m_b;
但是假设您要坚持使用printf
格式,这是一种实现方法。 尽管可以计算并计算出确切的空间量,但这是脆弱的。 如果对myTemplate
进行了更改,很容易导致缓冲区溢出。
一种计划是分配大量空间。 一种更可靠的方法是使用snprintf
首先确定缓冲区大小:
char const myTemplate[] = "a=%s,b=%s";
size_t expect_len = std::snprintf(NULL, 0, myTemplate, m_a.c_str(), m_b.c_str());
if ( expect_len == -1 )
throw std::runtime_error("snprintf failed");
std::vector<char> buffer(expect_len + 1);
std::snprintf(&buffer[0], buffer.size(), myTemplate, m_a.c_str(), m_b.c_str());
std::string returnStr(buffer);
在C ++ 11中,您实际上可以直接将snprintf
转换为returnStr
。
需要说明的是,整个printf
想法并不是很安全,因为如果myTemplate
包含了您不期望的内容,则可能导致未定义的行为。 (我想您是通过这种方式来允许自己在运行时指定其他格式的字符串的)。 因此,请谨慎使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.