当我在c ++中向后推送向量类上的元素时出现段错误

时间:2015-12-03 02:04:05

标签: c++

#include <iostream>
#include<vector>
#include <algorithm>
using namespace std;
class HasPtr {
private:
    int *count;
    string *str_ptr;
public:
    string getStrPtr(){
        return *str_ptr;
    }
    HasPtr(const string &str = string()) : count(new int(1)), str_ptr(new string(str)) {
        cout << str << endl;
    }

    HasPtr(const HasPtr &hasPtr) {
        count = hasPtr.count;
        str_ptr = hasPtr.str_ptr;
        *count = (*count) + 1;

    }

    HasPtr &operator=(const HasPtr &hasPtr) {
        if (this == &hasPtr) return *this;
        if (--*count) {
            delete str_ptr;
            delete count;
        }
        count = hasPtr.count;
        str_ptr = hasPtr.str_ptr;
        (*count)++;
    }

    bool operator<(const HasPtr &hasPtr) {
        return this->str_ptr < hasPtr.str_ptr;
    }

    ~HasPtr() {
        if (--*count) {
            delete str_ptr;
            delete count;
        }
    }

    friend void swap(HasPtr &ptr1, HasPtr &ptr2);
};

inline void swap(HasPtr &ptr1, HasPtr &ptr2) {
    using std::swap;
    swap(ptr1.count, ptr2.count);
    swap(ptr1.str_ptr, ptr2.str_ptr);
    cout << "swap" << endl;
}

int main() {

    vector<HasPtr> vecArr;
    HasPtr hp1(string("a"));
    HasPtr hp2(string("d"));
    HasPtr hp3(string("c"));
    HasPtr hp4(string("b"));

    vecArr.push_back(hp1);
    vecArr.push_back(hp2);
    vecArr.push_back(hp3);
    vecArr.push_back(hp4);

    for(int i = 0; i < 4 ; i++)
        for(int j = 0; j<4-i-j;j++){
            if(vecArr[j] < vecArr[j+1]){
                swap(vecArr[j],vecArr[j+1]);
            }
        }

    for(auto e : vecArr){
        cout<< e.getStrPtr() <<endl;
    }
    return 0;
}

代码粘贴在上面。在代码中,我定义了一个类和相应的复制操作,赋值操作等等。

当程序执行下面的语句时

   vecArr.push_back(hp3);

我的机器发生了段故障。我是C ++的新手。这个问题困扰了我几个小时。我不知道为什么。请帮我。 提前谢谢。

2 个答案:

答案 0 :(得分:0)

您的取消链接逻辑已损坏:

    if (--*count) {
        delete str_ptr;
        delete count;
    }

如果--*count为真,则删除,即不等于0.所以适当的条件应该是:

    if (not --*count) {
        delete str_ptr;
        delete count;
    }

您也不应该复制该代码,而是将其移至方法并从dtor和赋值运算符调用。

答案 1 :(得分:0)

我看到两个问题。首先是取消分配的守卫被否定了。如上所述,这将在每次发生副本时释放共享空间。将if (--*count)行更改为if (--*count == 0)以修复此问题。

第二个是赋值运算符不是return *this。使用返回值,链式赋值操作(例如a = b = c)将无法按预期工作。