Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Delete无法识别列表中的指针分配_C++_Pointers_Delete Operator - Fatal编程技术网

C++ Delete无法识别列表中的指针分配

C++ Delete无法识别列表中的指针分配,c++,pointers,delete-operator,C++,Pointers,Delete Operator,当我尝试在指向结构顶点的指针上调用delete时(使用顶点*v=new顶点分配),然后成功使用并存储在类析构函数中的std::list,我得到以下运行时错误: graphtake3(12325,0x100082000) malloc: *** error for object 0x100200340: pointer being freed was not allocated *** 由于应用程序运行良好,所有指针都被分配到堆栈跟踪中,但由于某些原因,delete似乎无法解除分配它们。这里发生

当我尝试在指向
结构顶点的指针上调用delete时(使用
顶点*v=new顶点分配),然后成功使用并存储在类析构函数中的
std::list
,我得到以下运行时错误:

graphtake3(12325,0x100082000) malloc: *** error for object 0x100200340: pointer being freed was not allocated
***
由于应用程序运行良好,所有指针都被分配到堆栈跟踪中,但由于某些原因,
delete
似乎无法解除分配它们。这里发生了什么,为什么delete不起作用

以下是相关的缩写代码:

#include <vector>
#include <list>
#include <iostream>
#include <string>

enum Color {BLACK, GREY, WHITE};

struct Vertex {
    int id;
    std::string name;
    Color color;

    Vertex();
    Vertex(std::string name);

    ~Vertex();

};
class Graph {
    std::vector<std::list<Vertex *>> adjList;

public:
    Graph();
    Graph (int nodeCount);

    ~Graph();

    int newVertex();
    int newVertex(std::string name);
    void newUnDirectedEdge(int v1, int v2);
    void newDirectedEdge(int v1, int v2);
    std::list<Vertex*> getConnections(int v);

    friend std::ostream& operator<<(std::ostream& os, const Graph& g);



};
#包括
#包括
#包括
#包括
枚举颜色{黑色、灰色、白色};
结构顶点{
int-id;
std::字符串名;
颜色;
顶点();
顶点(std::字符串名称);
~Vertex();
};
类图{
std::向量调整列表;
公众:
图();
图(int nodeCount);
~Graph();
int newVertex();
int newVertex(标准::字符串名称);
void newundiredge(int v1,int v2);
void newdirectedge(int v1,int v2);
std::list getConnections(intv);
friend std::奥斯特雷姆和操作员ID;
}
int图形::newVertex(标准::字符串名称){
顶点*v=新顶点();
向后推(标准::列表(1,v));
v->id=(int)adjList.size()-1;
v->name=name;
返回v->id;
}
void图::newUndirectedge(intv1,intv2){
newdirectedge(v1,v2);
newdirectedge(v2,v1);
}
无效图::newDirectedEdge(intv1,intv2){
Vertex*vertex2=adjList[v2].front();
adjList[v1]。推回(顶点2);
}
std::list Graph::getConnections(intv){
返回列表[v];
}

std::ostream&operator一旦您这样做,您就准备好面对灾难:

void Graph::newDirectedEdge(int v1, int v2) {
    Vertex * vertex2 = adjList[v2].front();
    adjList[v1].push_back(vertex2);
}
问题是您没有区分谁拥有指针。在这种情况下,您只是将指针复制到列表中。但是当您转到
~Graph
,您会删除列表中的所有指针。其中一些指针是通过
new
获得的,而另一些指针是通过上述函数复制的

因此,错误是正确的:指针没有分配。发生的情况是您已经删除了它,然后删除了它的一个副本

你需要重新考虑你的设计并考虑指针的所有权。或者你可以使用SeleG锤子的方法将所有的东西转换成代码> STD::SyrdYPPTR 。但是我不会真的推荐它。


图形的一种常见方法是存储所有顶点(在
std::vector
)中,然后像以前那样连接到一个单独的结构中。然后在析构函数中只需撕开向量。您甚至可以借此机会学习如何使用
std::unique_ptr

,您将面临灾难:

void Graph::newDirectedEdge(int v1, int v2) {
    Vertex * vertex2 = adjList[v2].front();
    adjList[v1].push_back(vertex2);
}
问题是您没有区分谁拥有指针。在本例中,您只需将指针复制到列表中。但是当您转到
~Graph
时,会删除列表中的所有指针。其中有些是通过
new
获得的,有些是通过上述函数复制的

因此错误是正确的:指针没有分配。发生的事情是你已经删除了它,然后你删除了它的一个副本

你需要重新考虑你的设计并考虑指针的所有权。或者您可以使用大锤式方法将所有内容转换为
std::shared\u ptr
。但我不建议这样做


图形的一种常见方法是存储所有顶点(在
std::vector
中),然后像您所做的那样连接到一个单独的结构中。然后在析构函数中,你只需撕开向量。您甚至可以借此机会学习如何使用
std::unique\u ptr

问题是否发生在newDirectedge函数中?
在它的实现中,先复制指针,再插入列表,然后对列表中的一个地址插入两个指针,第一次删除就可以了,第二次删除就可以了。。。崩溃…

问题是否发生在NewDirectedge函数中?
在它的实现中,先复制指针,再插入列表,然后对列表中的一个地址插入两个指针,第一次删除就可以了,第二次删除就可以了。。。崩溃…

请发布一个最小但完整的演示,读者可以尝试。这听起来像是一个三选一的问题。但是如果没有代码,就无法确定。@cheers和hth.-Alf好的,我添加了一个更完整的实现感谢更新,顺便说一句。add
Graph(const-Graph&)=delete(假设您使用的是C++11)到
图形
类decl。如果您的代码编译开始在不同的地方呕吐,那么您肯定违反了命令。@WhozCraig好的,我添加了我的
main()
。我还没有实现复制构造函数,所以我是,但在这种情况下,如何阻止delete工作?@他们的合作伙伴我刚刚运行了你的代码,在这种情况下不会,因为
Graph
从未被复制过(想想如果是这样会发生什么,两个
Graph
对象有两个
std::list
都包含相同的指针)。顺便说一句,这与您的实际问题密切相关。您的邻接列表可以共享指向同一顶点对象的指针。至少从我看到的情况来看,它们是这样做的。一旦您清除了列表,则包含指向刚清除的列表中的一个或多个顶点的指针的其他列表现在都会悬空,并使用它们调用und已定义的行为。请发布一个最小但完整的演示,读者可以尝试。这听起来像是一个三法则问题。但如果没有代码,就无法确定。@Cheersandhth.-Alf好的,我添加了一个更完整的实现感谢更新,顺便说一句。添加
图形(const Graph&)=delete;
(假设您使用的是C++11)到你的
图形
类decl。如果你的代码编译开始在不同的地方呕吐,你肯定是违反了。@WhozCraig好的,我添加了我的
main()
。我还没有实现一个复制构造函数,所以我是,但在这种情况下,如何停止delete的工作?@我刚刚运行的InnerParty
void Graph::newDirectedEdge(int v1, int v2) {
    Vertex * vertex2 = adjList[v2].front();
    adjList[v1].push_back(vertex2);
}