C++ Aborted core 在执行结束时转储

Posted

技术标签:

【中文标题】C++ Aborted core 在执行结束时转储【英文标题】:C++ Aborted core dumped at the end of its execution 【发布时间】:2019-03-02 13:53:58 【问题描述】:

我对 C++ 相当陌生,目前正在做关于向量的学校作业。头文件包含满足要求所需的功能的实现。我即将完成该程序,但不幸的是,在其执行结束时,它给出了“中止的核心转储”消息。我似乎无法弄清楚为什么会这样。一切都很顺利,直到结束。它是在分配测试期间发出该消息的。我需要你在这方面的专业知识。谢谢!

我的输出:

********** TestAssign **********
push_back 10 floats:
0 2 4 6 8 10 12 14 16 18 (size=10 capacity=16)
0 1 2 3 4 5 6 7 8 9 (size=10 capacity=16)
Assign: b = a, print a,b
0 2 4 6 8 10 12 14 16 18 (size=10 capacity=16)
0 2 4 6 8 10 12 14 16 18 (size=10 capacity=16)
Assign: a = a, print a
0 2 4 6 8 10 12 14 16 18 (size=10 capacity=16)
Aborted (core dumped)

学校的输出(正确的一项):

********** TestAssign **********
push_back 10 floats:
0 2 4 6 8 10 12 14 16 18 (size=10 capacity=16)
0 1 2 3 4 5 6 7 8 9 (size=10 capacity=16)
Assign: b = a, print a,b
0 2 4 6 8 10 12 14 16 18 (size=10 capacity=16)
0 2 4 6 8 10 12 14 16 18 (size=10 capacity=16)
Assign: a = a, print a
0 2 4 6 8 10 12 14 16 18 (size=10 capacity=16)

头文件(我的实现):

template <typename T>
vec 


private:
T* v;
int count;
int capacity;
public:

vector() //default constructor
    capacity=0;
    v = nullptr;
    count = 0;


vector(const vector& b) //copy contructor

count = b.count;
capacity = b.capacity;
v = new T[capacity];
for (int i = 0; i < capacity; i++)

    this->v[i] = b.v[i];

   

 vector(vector&& tmp): v(tmp.v),//move constructor
                      count(tmp.count),
                      capacity(tmp.capacity)

    tmp.v = nullptr;


~vector() //destructor

if (v != NULL);
    
        delete [] v;
        v = NULL;
    


void push_back(const T& t)

    if(count+1>capacity)

    capacity = std::max(2*capacity, 1);

    T* newData = new T[capacity];
    for(int i=0; i <count; i++)
    
        newData[i] = v[i];
    
    delete[] v;
    v = newData;

v[count++] = t;


T pop_back() 
    //..


size_t size() const
    
        //..
    

bool empty() 
 
  //..
   

 T operator[](unsigned index) const //subscript operator
 
     //...
 

 T& operator[](unsigned index) //subscript operator 
  
    //...
 

void clear()
    //...


void erase(T position)

  //...


void insert(int index, T number)

    //...


vector& operator = (const vector &rhs) //copy assignment

    ../


vector& operator=(vector&& rhs)  //move assignment

    if (this != &rhs) 
        delete[] v;
        this->v = rhs.v;
        rhs.v = nullptr;
    
    return *this;


template <typename T1>
friend void Print(const vector<T1>& s); //friend print

friend  void Print(const vector<unsigned char>& s);     //friend print if 
//unsigned

;
template <typename T1>
void Print(const vector<T1>& s)

    // std::cout << std::fixed << std::setprecision(2);
    for(int i = 0; i < s.count; i++) 
    
    std::cout<<s.v[i]<<" ";
    
    std::cout<< "(size=" << s.count << " " << "capacity=" << s.capacity << 
")";
    std::cout<<std::endl; 
    

void Print(const vector<unsigned char>& s)

    //...

主文件:

void TestAssign(void)

std::cout << "\n********** TestAssign **********\n";
cs150::vector<float> a, b;

std::cout << "push_back 10 floats:\n";
for (float i = 0; i < 10; i++) 
    a.push_back(2 * i);
    b.push_back(i);


Print(a);
Print(b);

std::cout << "Assign: b = a, print a,b\n";
b = a;
Print(a);
Print(b);

std::cout << "Assign: a = a, print a\n";
a = a;
Print(a);

【问题讨论】:

这似乎是learn how to debug your programs 的好时机。尤其是如何使用调试器来捕捉“正在运行”的崩溃,以定位它发生在代码中的时间和位置。 关于您的代码还有一些其他点可能值得一提:例如,您的复制构造函数复制 capacity 个元素,而不是 count 个元素。这实际上会导致未定义的行为,因为如果count &lt; capacity 那么您将复制未初始化的 数据。 【参考方案1】:

问题在于您的赋值运算符:

vector& operator = (const vector &rhs) //copy assignment

    v = rhs.v;
    return *this;

这会复制指针 v 而不是复制底层数组(您也忘记复制其他成员 countcapacity

因此,在 b = a; 之后,您最终会双重释放 ab 中的同一个数组,这会导致段错误。

将赋值运算符更改为更像复制构造函数:

vector& operator = (const vector &b) //copy assignment

    if (this != &b) 
        count = b.count;
        capacity = b.capacity;
        v = new T[capacity];
        for (int i = 0; i < count; i++)
        
            this->v[i] = b.v[i];
        
    
    return *this;


不相关的注释:你在析构函数中有一个额外的;

    if (v != NULL);
                  ^ here

我也暂时不考虑移动语义,除非你需要支持它。

【讨论】:

嗨@rustyx,感谢您的建议。但是,我现在将其作为输出: 0 2.8026e-45 5.60519e-45 8.40779e-45 1.12104e-44 1.4013e-44 1.68156e-44 1.96182e-44 2.24208e-44 2.52234e-44 (size=10容量=16) 我按照上面提到的你的代码得到了上面的输出。 是的,那是因为a = a; 没有意义。如果您想将其作为无操作来支持,则赋值运算符需要识别这种情况并且不要尝试复制任何内容。例如将其包装在if (this != &amp;rhs) 好吧,现在一切正常。非常感谢你们!

以上是关于C++ Aborted core 在执行结束时转储的主要内容,如果未能解决你的问题,请参考以下文章

在递归合并排序期间中止(核心转储)

Mongodb 停止工作:中止(核心转储)

在 Python 中使用 Ray 并行化任务,得到“Aborted (core dumped)”

在基数排序中,我得到 munmap_chunk(): invalid pointer 和 Aborted (core dumped)。为啥?

g++ 编译后的核心转储 + 与 jni 的链接以及随后使用 C++ 和 Java 执行应用程序

关于内核转储(core dump)的设置方法