- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
长话短说:我制作了一个模板双链表,将列表放在其他列表中会导致问题。这个问题已经解决了。
我正在测试双链表作为模板,我遇到了一个问题,将一个链表放在另一个链表中会出现以下错误:
(微软 Visual Studio 2010 速成版)
Windows has triggered a breakpoint in linkListTesting.exe. This may be due to a corruption of the heap, which indicates a bug in linkListTesting.exe or any of the DLLs it has loaded. This may also be due to the user pressing F12 while linkListTesting.exe has focus. The output window may have more diagnostic information.
搜索此特定错误会产生类似“确保您不使用未初始化的变量”的结果 - 在这种情况下,当我将列表告诉 push_back/push_front 等时,它应该初始化列表我。(不按 F12,这样场景就结束了。)
这是我的主要cpp->
#include "vcLLMK2.h"
int main(int argc, char *argv[])
{
vcList<vcList<int>> a;
vcList<int> b;
b.push_back(1);
a.push_back(b);
//ERROR HAPPENS HERE APPARENTLY
return 0;
}
将新条目(在本例中为“1”)推回(或推前,也尝试过)到“b”中效果很好。没有崩溃,没有愚蠢。将“b”插入“a”会导致应用程序吐出上述错误,触发断点,然后死掉。
我最近开始尝试使用 SDL,并打算使用一个列表作为 16 层的容器,这些层基本上是要渲染的 sprite/tiles/等列表。思路是,程序将遍历包含层列表中的每个条目,然后在移动到下一个之前渲染包含层中的每个对象。
“为什么不直接使用 std::list?”-因为那是作弊。
虽然很可能在此线程中回答的人能够指出我的列表结构和实现中的每个明显缺陷,而我很幸运地没有意识到这些缺陷,但我最关心的是什么-特别是导致这个特殊错误以及如何补救它。也就是说,我想问你们的问题是我构建的链表设置有什么问题导致上述 cpp 在运行时出错?
下面的链接列表结构是阅读以下页面的结晶:
http://www.codeproject.com/Articles/26631/Using-C-templates-for-functions-and-operators
http://www.cprogramming.com/tutorial/lesson15.html
http://geekswithblogs.net/MarkPearl/archive/2010/02/20/linked-lists-in-c.aspx
把它变成模板主要是对这个页面的创造性解释的结果:
http://www.cplusplus.com/doc/tutorial/templates/
这是我的链接列表模板类,有很多注释->
#pragma once
#ifndef vcLLMK2_H_INCLUDED
#define vcLLMK2_H_INCLUDED
#define NULL 0
//THIS IS ALL OUR NODE SHOULD EVER NEED
template <class T>
struct vcListNode
{
public:
T data;
vcListNode<T> *next;
vcListNode<T> *prev;
};
template <class T>
struct vcList
{
public:
vcListNode<T> *root;//the list's "start"
vcListNode<T> *end;//the list's "end"
vcListNode<T> *cur;//used to bounce around amongst entries
int size();//returns number of non-null entries
int count;//because keeping track of these is easier than iterating through every time
void setAt(T,int);//sets data in a node
void push_front(T);//inserts a new node at the beginning of the list
void push_back(T);//same thing but back of list
void removeAt(int);//kills a node at an arbitrary spot in the list
void clear();//deletes all of the nodes in the list
T getAt(int);//returns data from a node in the list
vcList<T>& operator = (const vcList<T>&);//used for setting list a's contents to list b
//EDIT COPYCONSTRUCTOR
vcList<T>(const vcList<T>&);//copyconstructor
vcList();// : root(NULL),end(root),cur(NULL),count(0){};
~vcList();
};
//constructor - sets everything to null and count to zero on init
template <class T>
vcList<T>::vcList()
{
root=NULL;
cur=NULL;
end=NULL;
count=0;
}
//destructor - deletes all nodes
template <class T>
vcList<T>::~vcList()
{
clear();
}
//deletes all nodes from root to end
template <class T>
void vcList<T>::clear()
{
if(root==NULL)//assume list has nothing in it, abort
return;
//set current targeted entry to root
cur = root;
//as long as we have somewhere to go...
while(cur->next!=NULL)
{
//go there
cur=cur->next;
//and destroy where we were
delete cur->prev;
}
//then destroy ourselves because nihilism is good for memory
delete cur;
}
//used to set the contents of a list equal to those of another
template <class T>
vcList<T>& vcList<T>::operator= (const vcList<T> &fays)
{
//for starters, clear ourselves of any unwanted garbagedata
clear();
//check the import list's root entry
cur = fays.root;
//if the list containing the values we are importing is empty, we're done, move along
if(cur==NULL)
return *this;
//otherwise, make a new node - it's our new root
vcListNode<T> *newEntry = new vcListNode<T>;
newEntry->data = fays.root->data;
newEntry->prev = NULL;
newEntry->next = NULL;
//set root/end to the new entry
root = newEntry;
end = newEntry;
//update our count
count=1;
//fire through the import-list's entries
//cur starts at root
while(cur->next!=NULL)//(count<fays.count)
{
//move to next entry
cur=cur->next;
//add it to our list, push_back should update the location of 'end' for us
push_back(cur->data);
}
//we should be done here, so go ahead and return everything
return *this;
}
//this is mostly for convenience
template <class T>
int vcList<T>::size()
{
return count;
}
//adds a new entry to the front of our linked list
template <class T>
void vcList<T>::push_front(T info)
{
//eat some memory
vcListNode<T> *newEntry;
newEntry = new vcListNode<T>;
//set our memory and all that neat stuff
newEntry->data = info;
newEntry->next = root;
newEntry->prev = NULL;
//if our linked list is not empty
if(root!=NULL)
//set root's previous link to point at our new entry
root->prev = newEntry;
//if our linked list does not have an assigned end yet
if(end==NULL)
//assume it's empty and set end to our entry
end=newEntry;
//update the position of our root in the list, the beginning now begins at the beginning again
root = newEntry;
//and since we added something to the list, we should probably update our count of things in the list
count++;
}
//this finds an element in the pointer-chain and sets its information
template <class T>
void vcList<T>::setAt(T info,int index)
{
//set our target to the root
cur=root;
//run through the list's entries until we're where we're supposed to be
while(index>0)
{
cur=cur->next;
index--;
}
//set the data in the cell/node/whatever to our input
cur->data=info;
}
//returns the data contained in a node at a position in the list
template <class T>
T vcList<T>::getAt(int meBro)
{
//set target to root
cur=root;
//progress through the list
while(meBro>0)
{
cur=cur->next;
meBro--;
}
//dig the data out of the entry and return it
return cur->data;
}
//adds an element-containing node to the end of the list-chain
template <class T>
void vcList<T>::push_back(T info)
{
//if our list already has entries, end shouldn't be null
if(end!=NULL)
//so just target our end slot
cur=end;
//if our list is empty, however
else
//target the root instead
cur=root;
//create our new node, put stuff in it, etc
vcListNode<T> *newEntry;
newEntry = new vcListNode<T>;
newEntry->data = info;
//we're adding to the END of the list so make next null
newEntry->next = NULL;
//if cur is NOT null, then theoretically we're pointed at the end of the list
if(cur!=NULL)
//set our new entry's previous pointer to the end
newEntry->prev = cur;
//cur IS null, which means the list is empty
else
//set our entry's previous pointer to be null, duh
newEntry->prev = NULL;
//if the end of our list exists
if(end!=NULL)
{
//set the next entry in the list to point at our new entry
end->next = newEntry;
//then set end to target the new entry
end=newEntry;
}
//and if our list does not have an end yet for some reason (read as: it's empty)
else
{
//set the root to our new entry
root = newEntry;
//set the end to our new entry as well, since there's only one entry in the list
end = newEntry;
}
//update count of number of objects in list
count++;
}
//this deletes/removes/destroys/obliterates a node at a location in the list
template <class T>
void vcList<T>::removeAt(int index)
{
//for starters - is what we're trying to kill even here?
if(index>=count)
//NOPE GET OUT
return;
//later on it might speed things up to check whether the distance from end or root is shorter
//for now, just start at the beginning
//target the root
cur=root;
//move through the list to the specified entry
while(index>0)
{
index--;
cur=cur->next;
}
//if the previous entry exists
if(cur->prev!=NULL)
//point its next at the entry after this one
cur->prev->next=cur->next;
//if the previous entry is NULL, it means we're at the root
//so tell root to scoot forward one entry
//if there's a forward to scoot to
else if(cur->next != NULL)
root = cur->next;
//if the next entry exists
if(cur->next!=NULL)
//set the next entry's previous pointer to point at the entry before the targeted one
cur->next->prev=cur->prev;
//if the next entry does not exist, we must be at the end of the list
//so tell the end of the list to scoot back one slot
//if there's a back-one-slot to go to
else if(cur->prev!=NULL)
end = cur->prev;
//remove the entry at the targeted location
delete cur;
//decrement our count
count--;
}
//EDIT -> Copy Constructor
//copy constructor, similar as suggested to the operator=
template <class T>
vcList<T>::vcList(const vcList<T>& fays)
{
//might not be completely necessary, but we're not hurting anything by making sure
clear();
//check the import list's root entry
cur = fays.root;
//if the list containing the values we are importing is empty, we're done, move along
if(cur==NULL)
return;//just return, constructors don't get return types
//otherwise, make a new node - it's our new root
vcListNode<T> *newEntry = new vcListNode<T>;
newEntry->data = fays.root->data;
newEntry->prev = NULL;
newEntry->next = NULL;
//set root/end to the new entry
root = newEntry;
end = newEntry;
//update our count
count=1;
//fire through the import-list's entries
//cur starts at root
while(cur->next!=NULL)//(count<fays.count)
{
//move to next entry
cur=cur->next;
//add it to our list, push_back should update the location of 'end' for us
push_back(cur->data);
}
//we should be done here, so go ahead and return everything
//return *this;
}
#endif
最佳答案
我认为您应该看一下 C++ 中最重要的概念之一,即按引用传递。 push_back 方法作为名为 info 的参数,它是您用来调用该方法的对象的拷贝。由于您没有明确告诉编译器如何创建 vsList 对象的拷贝,因此它将创建一个默认的复制构造函数,但它不会按预期工作。
所以当调用存储在对象“a”中的对象的析构函数时,您的代码确实会出现问题。因为它没有有效的指针,所以它会崩溃。您可以通过两种方式解决您的问题,更改 push_back(和所有其他方法)以通过“const 引用”而不是通过值接收 T 或实现复制构造函数。
关于c++ - 包含链表的链表给出堆损坏错误 : Why?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13148375/
我在使用带有 vector STL 的迭代器时遇到了这个错误。 代码:- #include #include void print_vec(std::vector vec) { auto
JAVA:两个引用“p”&&“pp”之间有区别吗? PrintStream p = new PrintStream(System.out); p.println("lol");
我尝试从主分支中拉出,但收到错误消息: $ git --no-optional-locks -c color.branch=false -c color.diff=false -c color.sta
我面临着一个让我抓狂的问题! 我有一个函数,这个: void load_weapons3(t_env *e, char *name, int x, t_weapon *w) { char
我正在尝试使用 CUDA 中的最小值、最大值、总和和平均值实现并行归约。 这是我目前的主要代码片段。 int main() { const auto count = 8; const
我知道 double free 或 corruption 错误通常是对 big 3 的违规,但在这种情况下,我找不到违规发生的地方。我有一个复制构造函数、析构函数和赋值运算符,适用于任何处理指针的东西
GTK+ 中的“focus”和“focus-in(out)-event”信号有什么区别?哪个先发射?它们与键盘(TAB)和鼠标点击有什么关系。他们互相依赖吗? 我问这个是因为我想在顶层窗口中跟踪当前聚
*** glibc detected *** /home/ghoshs/workspace/Simulator/Debug/Simulator: double free or corruption (
#include #include #include #include using namespace std; #define MAX_WEIGHT 1000000 class Set {
我在服务器上有两个分支一个叫 R2 的分支和一个叫 DEV 的分支我无意中登录了错误的服务器,进入了存储库并执行了GIT pull 源开发但是存储库在 R2 上。所以我意识到我的错误然后尝试通过做一个
我有一个包含循环的大约 1000 个顶点和 3000 个边的有向图。 我试图从给定的顶点找到所有下游(出)路径。 使用以下 Gremlin 查询时 g.V(45712).repeat(out().si
使用 Delphi XE 2 我试图确定缩放方向以将缩放效果应用于图像(TImage),但没有找到执行此操作的函数,并且图像的 OnGesture 事件中的 EventInfo 属性没有此信息. 我见
我正在尝试创建一个 Zoom_image 函数,它使用离散傅里叶变换来缩放灰度图像。如果图像大小小于或等于 4*4 但大小增加,我包含的代码可以工作。它给出“双重释放或损坏(出)中止(核心转储)”错误
当我执行 popAll 函数时,出现以下错误: 双重释放或腐败(出)中止(核心转储) 我想我已经将错误来源缩小到了这个函数。 IntegerStack 是我制作的一个简单的 ADT,其中包含一个名为
我有网络开发背景,我正在尝试创建类似于 this technique 的东西适用于 iOS(使用 Cocoa/Obj C)。我在谷歌搜索资源时遇到了很多困难,因为 iOS 中的“视差”往往指的是 iO
我想实现一个 faceted search对于我的一个项目。我正在使用 PHP5、Mysql 和 Symfony 1.4。显然社区指向Apache Solr这似乎正是我想要完成的。 问题是该网站将在不
我知道有 questions floating around当您没有提供明确的分支名称时,关于来自特定分支的 git pull,但是我想知道即使用户确实指定了不同的分支,是否也可以强制 pull 分支
我正在尝试将我的更改推送到 NAS 上的存储库。它以我无法理解的方式失败。 documentation声明默认情况下 push 仅适用于快进更新。很公平。所以我做了一个 git pull(我的 Rem
我刚开始使用 Oracle 的 Coherence 缓存,我注意到这一点:如果我在缓存中放入一个 ConcurrentHashMap 对象,当我检索它时,我可以看到它被转换为一个普通的 HashMap
我尝试创建一个连接到数据库的线程,从那里获取一些数据并打印到控制台。问题是当该线程完成时抛出异常: 双重免费或腐败(出局)中止(核心转储) 我尝试使用 sqlite3 和 pthread,但这两个并不
我是一名优秀的程序员,十分优秀!