为什么这会导致分段错误?

时间:2011-10-05 23:07:46

标签: c++

我一直用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  {

4 个答案:

答案 0 :(得分:1)

IntList *x;

这是未初始化的,它指向的价值也是如此。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

我立即看到了两件事。

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

2)你的prepend方法创建了一个loclion IntList,并返回它,这是一个禁忌。你正在返回一个已经在堆栈中的对象,现在已经不再有效了(虽然它可能有效。有趣的是,这个未定义的行为。)

答案 3 :(得分: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;

看起来你想使用address-of运算符将x指向y,即x=&y,但这将返回指向垃圾的指针。任何局部变量都在堆栈上分配,并在函数返回后立即释放。在指向离开范围的值之后,永远不要保留指向堆栈内存的指针,因为该内存很可能被快速重新分配给其他内容,从而防止崩溃。造成神秘的行为。

查找删除操作符。

相关问题