返回包含向量的空向量时的C++ Segfault

Posted

技术标签:

【中文标题】返回包含向量的空向量时的C++ Segfault【英文标题】:C++ Segfault when returning an empty vector containing vector 【发布时间】:2013-08-27 00:10:58 【问题描述】:

我在返回一个我没有预料到的空向量时遇到了一些问题。有人可以帮忙解释一下吗!

这是有问题的部分: - 我知道返回是相同的,它现在是一个占位符。

std::vector<std::vector<double> > PerceptronLayer::calculateLayer() 
    std::vector<std::vector<double> > result;

    if (vPerceptrons.size() == 0) 
        return result;
    

    return result;

但是,如果我通过设置一些虚拟数据来确保向量具有某些值,则该函数会按我的预期返回。

    std::vector<double> val;
    val.push_back(1.0);
    result.push_back(val);

GDB 输出:

Program received signal SIGSEGV, Segmentation fault.
0x000000000040ba60 in std::vector<double, std::allocator<double> >::operator[]     (this=0x0, __n=0)
at /usr/include/c++/4.7/bits/stl_vector.h:751
751        return *(this->_M_impl._M_start + __n); 

我可以通过不允许它在空数据上运行来保护该函数,但我不禁觉得我在这里缺少一些基本的东西。

谢谢, 乔

【问题讨论】:

你能告诉我们完整的代码吗?很难说您发布的代码有什么问题。 使用 GDB 命令up 遍历调用堆栈。看起来您的代码中的某处返回值被假定为非空。 啊,好的。是的,我想我找到了。我的回报是: std::vector<:vector> > results = pl.calculateLayer();如果我把它分成两行它可以工作: std::vector<:vector> > results;结果 = pl.calculateLayer(); @joeButler 这个结果看起来很有趣。单行使用复制构造函数,而双行使用赋值运算符重载。为什么会发生这种情况?我在 Visual Studio 上试过这个,但一切都很好。 gcc/g++ 对此有不同的实现吗? 错误出现在您没有向我们展示的代码中。您在从未检查过内容的向量上的至少一个位置使用了未经检查的 std::vector&lt;&gt;::operator[]() 数组运算符(即您在尝试访问 v[N] 之前没有 v.size() &gt; N)。 【参考方案1】:

修复者 - 有关详细信息,请参阅问题 cmets。

最初我从发布的函数返回来设置一个新的向量。它不喜欢它。

std::vector<std::vector<double> > results = pl.calculateLayer(); 

如果我将相同的代码分成两行,它会按预期工作。我猜 std::vector 的构造函数/副本不喜欢得到这个。

std::vector<std::vector<double> > results; 
results = pl.calculateLayer();

【讨论】:

我在 Visual Studio 2010 和带有 gcc 4.1.2 的 Centos 5.9 x86 上尝试了类似的代码(我在笔记本电脑上安装了一个带有虚拟盒的代码来验证这一点),但一切都很好。复制构造函数和赋值运算符重载具有这种显着差异是没有意义的。请问您使用的是什么平台和编译器? gcc -v 使用内置规范。目标:x86_64-linux-gnu 配置:../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.4.7-2ubuntu1' --with-bugurl=file:///usr/share/doc /gcc-4.4/README.Bugs --enable-languages=c,c++,fortran --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-linker-build-id --with -system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr /lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64 -linux-gnu --target=x86_64-linux-gnu

以上是关于返回包含向量的空向量时的C++ Segfault的主要内容,如果未能解决你的问题,请参考以下文章

C++,成员函数返回对包含指向 const 对象的指针的向量的 const 引用

声明结构时的向量分配

C++ OOP,输出对象指针向量时的空白控制台,不确定填充向量是不是正确

c++ 以最佳方式返回结构和向量

C++ 程序结束时的 thread_local 向量分段错误

如何使用返回向量的 C++ DLL