分段错误错误 C++

Posted

技术标签:

【中文标题】分段错误错误 C++【英文标题】:Segmentation fault error C++ 【发布时间】:2018-04-13 00:39:57 【问题描述】:

我正在编写一个简单的程序,将两个向量和 push_backs 交替转换为第三个向量,但是我得到一个分段错误错误(核心转储)。我做了一些研究,似乎我正在访问不存在或不应该存在的内存。我知道这是一个简单的解决方法,但我对 C++ 很陌生,所以任何事情都会受到赞赏。

vector<int> alternate(vector<int> a, vector<int> b)

    int n = a.size();
    int m = b.size();

    vector<int> c(n + m);

    int i;

    for(i = 0; i < a.size() and i < b.size (); i++)
    
        c.push_back(a[i]);
        c.push_back(b[i]);
    

    return c;


int main () 

    vector<int> a,b,c;
    int temp1;
    int temp2;

    while (temp1 != -1) 
        cin >> temp1;
        if(temp1 == -1) 
            break;
        
        a.push_back(temp1);
    

    while (temp2 != -1) 
        cin >> temp2;
        if(temp2 == -1) 
            break;
        
        b.push_back(temp2);
    

    c = alternate(a,b);

    int i;
    for(i = 0; i < c.size(); i++) 
        cout << c[i] << endl;
    

【问题讨论】:

通过使用没有值的变量,您可以立即获得未定义的行为。您应该首先解决这个问题,因为从本质上讲,未定义的行为可能会导致任何事情发生 如果您可以访问一个,您应该使用调试器单步执行您的代码。即使没有,您也可以使用一堆 std::cout 语句来向您展示代码的去向以及所有内容的价值。 您是否尝试过使用调试器单步执行您的程序并查看崩溃发生的位置? while (&lt;variable&gt; != 1) 更改为while (true)。您已经在循环中检查-1,无需再次检查。 @Barmar 或更好:while (std:cin &gt;&gt; temp &amp;&amp; temp != -1). 【参考方案1】:

据我所知,这里有两个问题:

    您在条件中使用了temp1temp2,但您没有初始化它们,这是一个UB。试试int temp1 = 0; int temp2 = 0;。 在函数alternate 中,您将使用两个输入向量之和来初始化返回向量,例如vector&lt;int&gt; c(n + m);,然后使用push_back 添加这些输入的元素。这样,您将在返回向量的开头有 n+m 零,然后是输入的元素。我很确定你不想要这个。您不需要为向量指定默认大小,只需使用push_back,或者如果您坚持使用默认大小,则为向量的索引分配值。

【讨论】:

对于#1,他应该在设置之前删除使用temp1temp2 的代码。不需要该代码。 @Barmar 没错,这是一种无用的仔细检查,但无论如何,始终初始化变量是一种好习惯。 @Hamed 谢谢你的帮助!你能够指出我正确的方向,我能够解决它。【参考方案2】:

您的代码存在一些问题,其中一些问题已在上文中提及。最重要的问题如下:

    temp1 和 temp2 未初始化。根据您的编译器,当在 while 循环中访问时,它们可能是 0 或某个随机数。 最终向量太大。当您创建 c 时,您正在创建它的大小为 n+m,因此它已经有那么多元素,每个元素的值都为 0。然后您将其他向量的元素相加,得到一个大致为 (n +m)*2 大小。 我在上面说“大致”是因为另一个问题是,除非 n==m,否则您的最终向量将丢失 a 和 b 中较大者的最后一个元素。您需要迭代到较大的 n 和 m,检查 while 循环以确保您可以安全地访问项目。

其他较小的问题如下:

    当您将 a 和 b 传递给备用时,您正在制作它们的副本。通过使用 const 引用,您可以避免复制。 虽然不太可能,但 a 或 b 可能包含比“int”引用的更多的项目。使用 size_t 是安全的。或者甚至更好地使用“auto”来让编译器自动确定正确的类型。 通过将临时变量引入“for”和“while”循环来限制它们的可见性。 尽可能使用较新的向量 for 循环来避免对索引的需求(交替使用是不可能的,但在写出最终结果时是可能的。

毕竟,结果应该如下所示:

#include <iostream>
#include <vector>

using namespace std;

vector<int> alternate(const vector<int>& a, const vector<int>& b)

    const auto n = a.size();
    const auto m = b.size();
    const auto N = max(n, m);

    vector<int> c;
    c.reserve(n+m);

    for(size_t i = 0; i < N; ++i)
    
        if (i < n) c.push_back(a[i]);
        if (i < m) c.push_back(b[i]);
    

    return c;


int main () 

    vector<int> a,b,c;

    while (true) 
        int temp;
        cin >> temp;
        if(temp == -1) 
            break;
        
        a.push_back(temp);
    

    while (true) 
        int temp;
        cin >> temp;
        if(temp == -1) 
            break;
        
        b.push_back(temp);
    

    c = alternate(a,b);

    for (auto val : c) 
        cout << val << endl;
    

【讨论】:

非常感谢你@Stephen!我是 C++ 的初学者(我相信你可以说出来),这是我大学课程作业的问题的一部分。感谢您做出如此详细的回复,它肯定会在未来帮助我 :) @Stephen 你能详细说明我是如何复制 a 和 b 的吗? 当您拥有“vector a”的方法签名时,它会复制“a”并将其传递给函数。您可以通过传入“const vector& a”来避免复制,它传入对对象的常量引用而不是对象的副本。常量引用本质上是一个内部指针,因此它很便宜,但是如果您尝试更改对象,编译器会给您错误。非常量引用“vector& a”将允许函数实际更改原始对象。【参考方案3】:

正如两个答案所指出的,未初始化的变量以及使我的“c”向量太大是罪魁祸首

【讨论】:

以上是关于分段错误错误 C++的主要内容,如果未能解决你的问题,请参考以下文章

指针数组 C++ 的分段错误

C++ 分段错误 OpenCV

在 C++ 中使用向量时出现分段错误

带有向量和字符串的 C++ 分段错误

在 C++ 中比较来自向量的字符串时出现分段错误

gcc,c++:静态字符串成员变量导致堆损坏/分段错误