2011-10-05 78 views
0

我一直在使用C++编写项目,通常我不会在分段错误方面遇到太多麻烦,但我是C++的新手。基本上,我做了一个指向IntList的指针,并调用prepend()从指针创建一个IntList。问题是prepend被调用时,它被卡在头文件的某处,justd退出。我不知道是什么导致了这一点,gdb告诉我它只是卡在头上。帮助将非常感激,就像提示或线索我做错了什么。谢谢。这是为什么导致分段错误?

IntList.h:

#ifndef _INTLIST_H 
#define _INTLIST_H 

#include <string> 
#include <cstring> 
using namespace std; 

class EmptyIntList; 

class IntList 
{ 
public: 
    static IntList *emptyList(); 
    //static IntList *fromString(string s);                                       

    virtual bool  isEmpty(); 
    IntList *prepend(int n); 
    virtual int  head(); 
    virtual IntList *tail(); 
    string toString(); 

    //  virtual int  length();                                        
    //  virtual IntList *append(IntList *lst);                                     

    //  virtual int  operator[](int n);                                      

    //  virtual ~IntList();                                          

protected: 
    IntList(); 
    IntList(IntList &); 
    //  const IntList &operator=(const IntList &);                                    
private: 
    int  data; 
    IntList *rest; 
}; 


IntList *operator+(IntList &lst1, IntList &lst2); 
ostream &operator<<(ostream &outStream, IntList *lst); 
ostream &operator<<(ostream &outStream, IntList &lst); 

#endif 

IntList.cpp:

#include "IntList.h" 
#include "EmptyIntList.h" 
#include <sstream> 

IntList::IntList(){} 

IntList *IntList::emptyList(){ 

    return ((IntList*)EmptyIntList::emptyList()); 

} 

bool IntList::isEmpty(){ 

    return false; 

} 

IntList *IntList::prepend(int n){ 

    IntList *x; 

    IntList y; 

    *x = y; 

    y.data = n ; 

    y.rest = x ; 

    return x; 

} 

int IntList::head(){ 

    return data; 

} 

IntList *IntList::tail(){ 

    return rest; 

} 

testIntList.cpp:

int main() 
{ 
    int n; 
    IntList *x; 
    n=6; 

    x->prepend(n); 
    // cout << x->toString();                                           
    return 0; 

} 

GDB步步​​:

8 int main() 
(gdb) step 
12 n=6; 
(gdb) 
14 x->prepend(n); 
(gdb) 
IntList::prepend (this=0x0, n=6) at IntList.cpp:30 
30 IntList y; 
(gdb) 
IntList (this=0x7fff93ecb3c0) at IntList.cpp:12 
12 IntList::IntList(){} 
(gdb) 
IntList::prepend (this=0x0, n=6) at IntList.cpp:32 
32 *x = y; 
(gdb) 
IntList::operator= (this=0x401650) at IntList.h:18 
18 { 
(gdb) 

Program received signal SIGSEGV, Segmentation fault. 
0x0000000000401361 in IntList::operator= (this=0x401650) at IntList.h:18 
18 { 
+0

你说你是C++新手?我会推荐[一本很好的C++入门书](http://stackoverflow.com/q/388242/46642)。是的,我对每个新手都说:) –

回答

0

任何尚未初始化的指针都有一个未定义的值,例如,它可能指向堆未分配区域中的随机垃圾。对未分配的堆区域的任何解引用都是分段错误。

您需要使用new运算符来分配一些堆内存并获取该内存的地址。 在主:

IntList *x; // IntList 
x = new IntList(); 

在前面加上:

IntList *x; 
x = new IntList(); // We now have no need for the local variable y 
x->data = n; 

它看起来像你想用地址的操作,在y以点X,即x=&y但这将返回一个指向垃圾。任何局部变量都在堆栈中分配,并在函数返回时立即解除分配。由于内存可能会被快速重新分配给其他内容,因此在指向内存的范围之后,切勿保留指向堆栈内存的指针,以防止崩溃造成神秘行为。

查找删除操作符。

0

下面只是定义了一个指针,而不是malloc内存,所以它指向内存中的一个随机地址: IntList * x;

当您尝试为其分配值“y”时,程序崩溃。

0

我明白了两件事。

1)主要是,你没有分配一个IntList,只是一个IntList *指向垃圾。当你调用x-> prepend时,你正在使用未初始化的内存。在调用方法之前,您需要一个具体的对象。

2)你的prepend方法创建一个locaion IntList,并返回它,这是一个否定的。你回到那个曾经在栈上,现在不再有效的对象(虽然它可能工作,有时,有趣的事情,是不确定的行为。)

+0

'prepend'的退货很好。 'prepend'中的UB与main相同:'x'未初始化。 –

1
IntList *x; 

这是未初始化的,所以是值它指向。

相关问题