微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C++11 中的内存分配不稳定

如何解决C++11 中的内存分配不稳定

我的软件得到的结果不稳定,我想了解为什么以及如何修改我的代码以获得一致的结果。为了说明这一点,我准备了该软件的模拟样本;下面,我有 2 个主要类,MotherDaughter;这些是我的主要数据结构,我在许多其他数据结构中使用 Mother。因此,它本质上是一个抽象类,但不能是纯粹的抽象类,因为一些可观察对象也直接依赖于它,所以我不能在其中编写(据我所知)纯虚函数类定义如下;

#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
#include <vector>

using namespace std;

class Mother {
    private:
        double some_var_;

    public:
        Mother() {some_var_ = 0.;}

        virtual ~Mother() {}

        virtual void print() const
        {
            std::cout << "printing from mother " << some_var_ << std::endl;
        }

        virtual void setvar(double v) {some_var_ = v;}

        virtual const double var() const {return 0.;}
};

class Daughter : public Mother
{
    private:
        double new_var_;

    public:
        Daughter() {new_var_ = 0.;}

        virtual ~Daughter() {}

        void print() const
        {
            std::cout << "printing from Daughter " << new_var_ << std::endl;
        }

        void setvar(double v) {new_var_=v;}

        const double var() const {return new_var_;}
};

我通过定义如下的 collection 类与这些数据结构进行交互;

class collection
{
    private:
        std::vector<Daughter> daughters_;

    public:
        collection () {Reset();}

        virtual ~collection() {}

        void Reset() {daughters_.clear();}

        Daughter* GetNewDaughter()
        {
            daughters_.push_back(Daughter());
            return &daughters_.back();
        }

        const std::vector<Daughter>& daughters() {return daughters_;}
};

鉴于这些,我定义了一个 filter 函数来修剪这些数据结构;

template <class T,typename FN>
std::vector<const T*> filter(std::vector<T> objects,FN func)
{
    std::vector<const T*> filtered;
    for (auto &obj: objects)
    {
        if (func(&obj)) filtered.push_back(&obj);
    }
    return filtered;
}

代码体如下;

int main(int argc,char** argv)
{
    collection* col = new collection();
    for (unsigned int i=0; i<5; i++)
    {
        Daughter* current = col->GetNewDaughter();
        current->setvar(double(i)*2.);
    }

    std::vector<const Daughter*> filt1 = filter(col->daughters(),[] (const Daughter* d) {return d->var() > 2.;});

    std::vector<const Daughter*> filt2;
    for (unsigned int i=0; i<col->daughters().size(); i++)
    {
        const Daughter * current = &(col->daughters())[i];
        if (current->var() > 2.) filt2.push_back(current);
    }

    std::cout << "first filtered" << std::endl;
    for (const Daughter * c: filt1) c->print();
    std::cout << "second filtered" << std::endl;
    for (const Daughter * c: filt2) c->print();

    return 0;
}

如您所见,我定义了两个过滤器,一个使用 filter 函数,另一个使用手动,我希望看到相同的结果。但是,我运行了 4 次代码,每次都得到不同的结果;

g++ -Wall -std=c++11 -O3 -fPIC main.cpp -o main
$ ./main
first filtered
printing from Daughter 4
printing from Daughter -2.68156e+154
Segmentation fault: 11
$ ./main
first filtered
printing from Daughter 4
printing from Daughter 0
Segmentation fault: 11
$ ./main
first filtered
printing from Daughter 4
printing from Daughter 2.31584e+77
Segmentation fault: 11
$ ./main
first filtered
printing from Daughter 4
printing from Daughter 6
printing from Daughter 8
second filtered
printing from Daughter 4
printing from Daughter 6
printing from Daughter 8

如您所见,由于某种原因,前 3 次运行完全是垃圾,而最后一次运行符合预期,但似乎完全是随机的,所以我相信我在内存分配过程中做错了。如果有人能告诉我我做错了什么以及为什么我做错了,以及我应该如何更改代码以避免这种不稳定,我将不胜感激。

谢谢!

解决方法

尝试改变:

std::vector<const T*> filter(std::vector<T> objects,FN func)

std::vector<const T*> filter(const std::vector<T>& objects,FN func)

恕我直言,您在调用 filter 时创建了 vector 的新实例(副本)。 您“过滤”了 vector 的新实例,在过滤器完成后,向量被删除,结果 std::vector filt1 具有无效指针。

,

叶夫根尼是对的。只是对问题的一个小描述。事情是 filter 函数返回指向在调用 filter 函数时创建的临时对象的指针向量(第一个参数 - 向量)。函数完成工作后,filt1 存储指向被销毁对象的无效指针。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。