c++ - 将指针插入 C++ vector 并进行清理

标签 c++ pointers memory-leaks vector push-back

我正在不同系统之间转换一些代码,我有一个关于 c++ vector 的问题。

如果我这样做:

在头文件中:

struct Vertex
{
    float x;
    float y;
    float z;
}

struct submesh
{
    Vertex *meshdata;
}

std::vector<submesh> meshes;

在c++文件中的例程中:

{
    Vertex *data = new Vertex[1024];

    submesh g;
    g.meshdata = data;
    meshes.push_back(g);

    delete [] data;
}

我会遇到麻烦吗?我的假设是,一旦我对其调用 delete,该 vector 将包含一个指向不再有效的数据的指针。我是否需要为 Vertex 编写复制构造函数以便首先复制数据?

附加:

问题更多是关于如何将指向已分配内存的指针放入 std::vector<> 并仍然清理本地分配的数据。本质上,我如何将数据复制到 vector 中,以便我仍然可以清理我的拷贝。

原始代码在 DirectX 中。我正在将它移植到 iPhone。原始代码在例程中使用以下方式在本地分配子网格:

{
    ID3DXMesh* subMesh = 0;
    D3DXCreateMesh(SubGrid::NUM_TRIS, SubGrid::NUM_VERTS, D3DXMESH_MANAGED, elems, gd3dDevice, &subMesh));

    //
    // ... do some magical things to submesh
    //

    SubGrid g;
    g.mesh = subMesh;
    g.box  = bndBox;
    mSubGrids.push_back(g);
}

我试图复制如何将 ID3DXMesh 添加到 vector ,然后在例程中失去它的范围。

由于我无权访问 D3DXCreateMesh(),我想我会简单地分配我需要的顶点,将它们放入 vector 中,然后清理。

抱歉,我不想透露细节,因为问题很简单,我如何分配数据 block ,将指针放入 std::vector<>,然后清理本地分配的内存. :)

我假设必须在某处编写一个复制构造函数。只是不确定在哪里或如何。

子网格如下所示:

struct SubGrid
{
    ID3DXMesh* mesh;
    AABB box;

    // For sorting.
    bool operator<(const SubGrid& rhs)const;

    const static int NUM_ROWS  = 33;
    const static int NUM_COLS  = 33;
    const static int NUM_TRIS  = (NUM_ROWS-1)*(NUM_COLS-1)*2;
    const static int NUM_VERTS = NUM_ROWS*NUM_COLS;
};

他们添加到的 vector 看起来像:

std::vector<SubGrid> mSubGrids;

最佳答案

不要在不需要时直接动态分配,在这种情况下您不需要。由于您要填充自己的子网格数据而不是使用 ID3DXMesh,因此该数据的容器应该符合 RAII。如果我正在编写这个代码,我会完全删除 submesh 类并只使用:

// vector containing list of vertices.
typedef std::vector<Vertex> SubMesh;

您的 SubGrid 类可以成为一个简单的容器,作为其属性之一,它包含一个 submesh 集合。我注意到您还有一个用于盒子对象的 AABB 类。您将继续将其保留在 SubGrid 中。我不必在这里工作,所以我正在制作其中的一些内容,但类似于以下内容:

// a simple 3-value triplet of floats
struct Vertex
{
    float x,y,z;
};

// a Submesh is an arbitrary collection of Vertex objects.
typedef std::vector<Vertex> SubMesh;

// I'm defining AABB to be an 8-vertex object. your definition
//  is likely different, but I needed something to compile with =)
typedef Vertex AABB[8];

class SubGrid
{
public:
    SubGrid() {};

    // comparator for container ordering
    bool operator <(const SubGrid&);

    // submesh accessors
    void setSubmesh(const SubMesh& mesh) { submesh = mesh;}
    SubMesh& getSubmesh() { return submesh; }
    const SubMesh& getSubmesh() const { return submesh; }

    // box accessors
    AABB& getBox() { return box; }
    const AABB& getBox() const { return box;}

private:
    SubMesh submesh;
    AABB box;
};

// arbitrary collection of SubGrid objects
typedef std::vector<SubGrid> SubGrids;

将此添加到全局 SubGrid 集合 g 时,您有多种可能性。你可以这样做:

// declared globally 
Subgrids g;

// in some function for adding a subgrid item
SubGrid subgrid;
AABB& box = subgrid.getBox();
SubBesh& submesh = subgrid.getSubmesh();

// ... initialize your box and submesh data ...

g.push_back(subgrid);

但是您会复制大量数据。要加强内存访问,您总是可以这样做:

// push an empty SubGrid first, then set it up in-place
g.push_back(SubGrid());
Subgrid& subgrid = *(g.back());
AABB& box = subgrid.getBox();
SubMesh& submesh = subgrid.getSubmesh();

//... initialize your box and submesh data ...

这将建立对刚刚添加到全局集合的 SubGrid 的引用,然后允许您就地修改它。这只是许多可能的设置选项之一。应该注意的是,如果你的工具链中有 C++11(如果你在 MacOS 或 iOS 上这样做,你可能会这样做,因为 Apple LLVM 4.2 的 clang 在 C++11 合规性方面非常好)这个明智地使用移动构造函数移动赋值运算符 可以获得更高的效率。

最重要的是,不会看到newdelete

无论如何,我希望这能给你一些想法。

关于c++ - 将指针插入 C++ vector 并进行清理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14796670/

相关文章:

c++ - 为什么此代码在找到后不突出显示搜索词?

pointers - 在Golang中将结构指针转换为接口(interface)指针

c - 指向指针的指针与指针

iPhone Objective-C 自动发布泄露

c - fclose 似乎不能在 C 中工作

c++ - 在计算着色器的无序访问 View 中写入 TextureCube

c++ - 指针错误传值

c++ - C++ 中带指针的简单代码的行为

c++ - 为什么 Visual Studio CRT 内存报告显示 CRT block

c++ - _CrtIsValidHeapPointer(block) 加载异常