删除临时指针时出现segfault
Seg fault when deleting temporary pointer
我使用gdb来查找段故障的确切行。它在dequeue函数中作为注释注释。
这是整个队列类。
当队列中有两个对象和哨兵时,调用dequeue()
时会出现故障。
template <typename T>
void Queue<T>::clear()
{
while(!isEmpty())
dequeue();
}
template <typename T>
void Queue<T>::enqueue(const T& x)
{
if(isEmpty())
{
Queue<T>* temp = new Queue<T>;
m_data = x;
m_next = temp;
return;
}
Queue<T>* temp = this;
while(temp->m_next != NULL)
{
temp = temp->m_next;
}
Queue<T>* node = new Queue<T>();
temp->m_data = x;
node->m_next = temp->m_next;
temp->m_next = node;
return;
}
template <typename T>
void Queue<T>::dequeue()
{
if(isEmpty())
return;
if(m_next != NULL)
{
Queue<T>* temp = m_next;
m_data = temp->m_data;
m_next = temp->m_next;
delete temp; //Seg fault here
}
return;
}
template <typename T>
const T& Queue<T>::front() const throw (int)
{
if(isEmpty())
throw 0;
return m_data;
}
template <typename T>
bool Queue<T>::isEmpty() const
{
return (m_next==NULL);
}
template <typename T>
int Queue<T>::size() const
{
int size = 0;
const Queue<T>* temp = this;
while(temp->m_next != NULL)
{
temp = temp->m_next;
size++;
}
return size;
}
对不起,我以为我已经发布了队列类:
template <typename T>
class Queue : public AbstractQueue<T> {
public:
Queue(){m_next = NULL;};
virtual void clear();
virtual void enqueue(const T& x);
virtual void dequeue();
virtual const T& front() const throw (int);
virtual bool isEmpty() const;
virtual int size() const;
~Queue(){
clear();
return;
};
private:
T m_data;
Queue* m_next;
};
它继承自这个类:
template < typename T >
class AbstractQueue
{
public:
// Purpose: clears the queue
// Postconditions: the queue is now empty
// -- PURE VIRTUAL
virtual void clear() = 0;
// Purpose: enqueue an element into the queue
// Parameters: x is the item to add to the queue
// Postconditions: x is now the element at the end of the queue,
// -- PURE VIRTUAL
virtual void enqueue(const T& x) = 0;
// Purpose: dequeues
// Postconditions: the element formerly at the front of the queue has
// been removed
// Dequeueing from an empty Queue produces no errors, queue remains empty.
// -- PURE VIRTUAL
virtual void dequeue() = 0;
// Purpose: looks at the front of the queue
// Returns: a reference to the element currently in front of the queue
// Exception: if the queue is currently empty, throw SOMETHING!!
// -- PURE VIRTUAL
virtual const T& front() const = 0;
// Purpose: Checks if a queue is empty
// Returns: 'true' if the queue is empty
// 'false' otherwise
// -- PURE VIRTUAL
virtual bool isEmpty() const = 0;
// Purpose: Returns the size of a queue.
// Returns: the number of elements in the Queue
// -- PURE VIRTUAL
virtual int size() const = 0;
// ----------------
// Purpose: Destructor
// -- VIRTUAL
virtual ~AbstractQueue() {};
};
在此代码中:
Queue<T>* temp = m_next;
m_data = m_next->m_data;
m_next = m_next->m_next;
你不检查m_next是否为非空(如果你在列表的末尾),所以你开始对空指针解引用,所有的赌注都取消了。
对我来说,enqueue()
中的下面一行看起来有点奇怪。
Queue<T>* node = new Queue<T>();
每次都创建一个新的Queue。
意图可以是下面的吗?
T * node = new T;
好吧,我不给你鱼,我教你怎么钓鱼…
当你得到segmentation fault
,这意味着操作系统已经检测到内存访问错误。这通常发生在C/c++中使用指针时。指针是非常危险的,必须小心对待。
如何检测问题发生的位置当您的程序接收到SEGFAULT
时,Linux提供的信息并不多,但是它提供了很多信息。你只需要知道如何"读"它。
coredump,是发生分段故障时的内存、堆栈和变量的图片。运行它
gdb myapp core
其中myapp是应用程序的可执行文件,core是coredump。现在您将看到如下内容:
GNU gdb 19991004
Copyright 1998 Free Software ���.�
Core was generated by `testit'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /usr/lib/libstdc++-libc6.1-1.so.2...done.
Reading symbols from /lib/libm.so.6...done.
Reading symbols from /lib/libc.so.6...done.
Reading symbols from /lib/ld-linux.so.2...done.
#0 0x823221a in main () at blabla.c:3
10 *i++;
它会告诉你到底是哪一行出了问题。如果您想知道您是如何到达那一行的,请键入bt
这将向您展示从应用程序main()到实际故障的回溯,包括传递给函数的参数。
我认为一旦你确切地知道分割错误发生在哪里,你就会更容易解决它。
一些笔记:
如果没有创建coredump。在控制台中输入:
ulimit -c unlimited
你需要使用-g来编译你的程序,以便在gdb中启用有意义的符号名称。
相关文章:
- Segfault如果更改派生类的指针值
- 通过嵌套的lambda中的值捕获指针导致Segfault
- 将指针存储到SQLITE3数据库中的类别抛出segfault
- 尽管文件指针正确,但在fclose()期间的segfault
- C Segfault在指针比较上
- 无法删除旧的指针(segfault)
- 当删除NULL指针(C/C )时,可以保证SegFault
- 删除指向流的类成员指针时出现Segfault
- 调整指针segfault的向量大小
- 简单的引用变量赋值导致对象的全局指针出现segfault
- 尝试从插入的.dll中的指针读取字符串时出现Segfault
- push_back对象的指针会导致segfault
- 指针,将参数传递给main和segfault
- 使用共享指针访问单例子类时的SEGFAULT
- 一个未初始化的指针是如何在cin中创建SegFault的
- 可以在不取消引用的情况下递增指针,但仍然存在segfault或具有其他(未)定义的恶意
- 在C++中使用矢量中的指针后的Segfault
- 通过多个函数传递指针并获取segfault
- 将segfault转换为空指针
- c++:初始化指针队列时获取segfault