变量超出范围后,避免我的指针指向无效内存

时间:2014-05-26 12:48:47

标签: c++ pointers

以下代码有效(Visual Studio 2013)

#include <vector>
#include <iostream>
#include <algorithm>
#include <memory>

using namespace std;

class base {
    ...

    virtual ostream& toStream(ostream& str) const {
        str << "Data: " << this->getData() << " Changes: " << this->getChanges();

        return str;
    }
};

class A : public base { ... };

class B : public base { ... };

ostream& operator<<(ostream& str, const base& base) {
    return base.toStream(str);
}

int main() {
    vector<base*> v(4);

    base myBase;
    B myB;

    {
        A myA;
        v[0] = &myBase;
        v[1] = &myA;
        v[2] = &myB;
        v[3] = v[1];
    }

    v[0]->setData(9);
    v[1]->setData(19);
    v[2]->setData(29);
    v[3]->setData(39);

    v[0]->setData(8);


    cout << "v[1]: " << v[1] << endl;
    cout << "v[3]: " << v[3] << endl;


    for each (base* b in v)
    {
        b->toStream(cout) << endl;
        cout << (*b) << endl;
    }

    return 0;
}

但我知道,v[1] = &myA是危险的,因为myA在块结束时被摧毁。
但是如何在没有风险的情况下做这样的事情呢?

有什么方法可以避免在变量被破坏但内容仍然被指针指向时仍然存在于堆栈上的变量内容的破坏?

编辑:
也许这样的事情会有些相同:

void addObject(object o) {
    this->myRefVector.push_back(&o);
}

4 个答案:

答案 0 :(得分:2)

{
    A myA;
    v[0] = &myBase;
    v[1] = &myA;
    v[2] = &myB;
    v[3] = v[1];
}

块退出后,大括号内定义的任何内容都不再存在。据我所知,这些括号没有任何意义 - 删除它们,或者在大括号外面(之前)启动myA

答案 1 :(得分:0)

如何首先创建元素对象?

int main() {
    base myBase;
    A myA;
    B myB;

    vector<base*> v(4);

    v[0] = &myBase;
    v[1] = &myA;
    v[2] = &myB;
    v[3] = v[1];

    v[0]->setData(9);
    v[1]->setData(19);
    v[2]->setData(29);
    v[3]->setData(39)

    .
    .
    .
}

这样容器v总是在它指向的对象之前被销毁。

答案 2 :(得分:0)

您始终可以在堆上创建myA onject,而不是在堆栈上创建。

A* myA = new A();

但是你应该在完成使用后更改分配和删除指针。

{
// code
v[1] = myA;
// code
}
// code
// somewhere 
delete myA;

或者您可以删除这些括号。或者在括号外声明myA。

答案 3 :(得分:0)

您可以使用std :: shared_ptr和自定义删除器来避免删除现有资源:

#include <vector>
#include <memory>

void no_delete(void*) {};

int main() {

    int a = 0;
    int b = 0;
    int c = 0;
    std::vector< std::shared_ptr<int> > v(4);

    // assign/create resources
    {
        v[0] = std::shared_ptr<int>(&a, no_delete);
        v[1] = std::shared_ptr<int>(&b, no_delete);
        v[2] = std::shared_ptr<int>(&c, no_delete);
        v[3] = std::make_shared<int>(1);
    }
}