c++11 - 按值从局部变量返回初始化列表
问题描述
尝试执行以下操作时,我得到 free(): invalid size :
std::u32string FileMappingWrapper::getCurrCharPosAsString() const
{
std::u32string progressString;
size_t currLine = getFrameStartPos();
while (currLine)
{
progressString.push_back(U'0' + currLine % 10);
currLine /= 10;
}
return {progressString.rbegin(), progressString.rend()}; <- I expect that std::u32string rvalue constructor or RVO will be used
}
然后我从另一个调用这个函数:
void CurrFrameVisitor::visit(windows::NCursesProgressWindowDecorator *window)
{
RawWindowBuffer newBuffer(window->getWindowDimensions().first, window->getWindowDimensions().second);
auto progress = window->getParentWindowHandler()->getFileMapper()->getPrintedProgress();
auto lineNo = window->getParentWindowHandler()->getFileMapper()->getCurrCharPosAsString();
std::copy(progress.begin(), progress.end(), newBuffer[0].begin());
newBuffer[0][progress.size()] = '%';
if (lineNo.empty()) {
lineNo.push_back(U'0');
}
std::copy(lineNo.begin(), lineNo.end(), std::next(newBuffer[0].begin(), progress.size() + 2));
window->print(std::move(newBuffer)); <- All is good untill this point
}
我知道该示例无法编译,但这是我调试代码的内容,我可以看到调用访问者时一切都很好,直到堆栈展开。试图销毁从初始化列表创建的变量auto lineNo = window->getParentWindowHandler()->getFileMapper()->getCurrCharPosAsString();
会引发 SIGABRT。所以我的问题是:从本地对象按值重新调整初始化列表是否像我所做的那样安全有效?谢谢
更新:
这是由于 newBuffer 数组不够大导致的错误。为什么然后 gdb 告诉 SIGABORT 是在销毁 lineNo 对象时?来自 gdb 的输出:
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff6c07801 in __GI_abort () at abort.c:79
#2 0x00007ffff6c50897 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff6d7db9a "%s\n") at ../sysdeps/posix/libc_fatal.c:181
#3 0x00007ffff6c5790a in malloc_printerr (str=str@entry=0x7ffff6d7bda0 "free(): invalid size") at malloc.c:5350
#4 0x00007ffff6c5ee2c in _int_free (have_lock=0, p=0x7fffec000dd0, av=0x7ffff6fb2c40 <main_arena>) at malloc.c:4161
#5 __GI___libc_free (mem=0x7fffec000de0) at malloc.c:3124
#6 0x000055555556b05e in __gnu_cxx::new_allocator<char32_t>::deallocate (this=<optimized out>, __p=<optimized out>) at /usr/include/c++/7/ext/new_allocator.h:125
#7 std::allocator_traits<std::allocator<char32_t> >::deallocate (__a=..., __n=<optimized out>, __p=<optimized out>) at /usr/include/c++/7/bits/alloc_traits.h:462
#8 std::__cxx11::basic_string<char32_t, std::char_traits<char32_t>, std::allocator<char32_t> >::_M_destroy (__size=<optimized out>, this=0x7ffff68274a0) at /usr/include/c++/7/bits/basic_string.h:226
#9 std::__cxx11::basic_string<char32_t, std::char_traits<char32_t>, std::allocator<char32_t> >::_M_dispose (this=0x7ffff68274a0) at /usr/include/c++/7/bits/basic_string.h:221
#10 std::__cxx11::basic_string<char32_t, std::char_traits<char32_t>, std::allocator<char32_t> >::~basic_string (this=0x7ffff68274a0, __in_chrg=<optimized out>)
at /usr/include/c++/7/bits/basic_string.h:647
#11 mirror::printer::CurrFrameVisitor::visit (this=<optimized out>, window=0x5555557c8040) at src/printer/CurrFrameVisitor.cpp:23 <- this is the line auto lineNo = window->getParentWindowHandler()->getFileMapper()->getCurrCharPosAsString();
解决方案
推荐阅读
- android - Flutter:出现键盘时背景图像正在挤压
- go - 成对迭代字符串数组以创建地图
- c# - FindReferencesAsync 不返回跨项目的引用
- node.js - NodeJS 中的 Firestore 实时更新连接
- c# - 在将 base64image 保存到 Image 到文件夹 GDI+ 期间发生 C# Asp.net mvc 错误
- php - 获取当前 URL 并保存到 XML 文件
- python - 无法在 aws s3 上查看文件(403 禁止)
- python - 如何修复 Python 中的 AttributeError?
- python - 如何让 fit 函数定义拟合范围?
- android - 如何使用 DrawerButton、SearchView 和半透明状态栏创建 Google 地图,例如 Toolbar,以便在状态栏后面可以看到地图?