指向基类的指针在while循环中丢失,导致段错误。 C ++

时间:2014-05-17 05:03:37

标签: c++ pointers while-loop base-class abstract-base-class

此代码使用while循环来获取用户输入并执行相应的命令 - 为简洁起见,我将其减少为2个命令。
Oblock对象是正确创建的(命令" O"),指向基类的指针也是如此。似乎对两个对象的调用也正常工作。 但是,在返回到while循环后,指向该对象的指针似乎丢失,并且尝试访问其成员(命令" t")会导致段错误。 我已经包含了下面的示例代码 - 之后我的问题就出现了。

#include<vector>
#include<iostream>
#include<string.h>

using namespace std;

class Tetramino {
    private:
        int squareSize;
        vector<string> myShape;
    public:
        void setValues(int size) {
            squareSize = size;
            myShape = vector<string> ((size*size), ".");
        }
        string getValues(int i) {
            return myShape[i];
        }
        int getSize() {
            return squareSize;
        }
};

class Oblock : public Tetramino {
    public:
    Oblock() {
        setValues(2);
    }
};

main () {
    string input;
    bool runProgram = true;
    Tetramino *pBlock;

    while (runProgram) {
        cin >> input;
        if (input == "O")
            {
                Oblock myBlock;
                cerr << "0thi: " << myBlock.getValues(0) << endl;
                Tetramino *pBlock = &myBlock;
                cerr << "0thi: " << pBlock->getValues(0) << endl;
            }
        if (input == "t")
            {
                cerr << "0thi: " << pBlock->getValues(0) << endl;
            }
        }
    return 0;
}
  • 退出if语句后对象是否被解构?
  • 是否有更好的方法可以反复获取用户输入?

提前感谢任何建议!我搜索了与此类似的问题,无法找到适合我需求的问题。

4 个答案:

答案 0 :(得分:3)

Tetramino *pBlock在其范围内是本地的。您正在使用main中的if内的myBlock上的那个上方隐藏。{/ 1>

此外,new是本地的并且将被破坏 - 你将有一个悬空指针。您应该使用delete(以及Tetramino *pBlock = &myBlock; ...)

进行分配 当您处理“O”输入(并处理前一个输入的pBlock = new Oblock;)时,

而不是delete pBlock执行{{1}}。

答案 1 :(得分:1)

 if (input == "O")
 {
     Oblock myBlock;
     cerr << "0thi: " << myBlock.getValues(0) << endl;
     Tetramino *pBlock = &myBlock;
     cerr << "0thi: " << pBlock->getValues(0) << endl;
 }

具有自动存储持续时间的对象(通常称为函数局部变量)具有从其声明开始并在最近的封闭块}标记结束处结束的生命周期。因此myBlock在此if语句的末尾被销毁,不能再次使用。

另请注意,您已声明了两个名为pBlock的不同指针。分配内部的那个对前一个没有任何作用,它仍未被初始化。

答案 2 :(得分:1)

回答你的第一个问题:是的,声明

Oblock yblock;

在堆栈上创建Oblock的实例。当代码离开相应的块时它被销毁,因此在此之后任何指针都变为无效。要创建一个可以存活的对象,请使用new在堆上创建对象。

答案 3 :(得分:0)

myBlock超出范围(if语句关闭的位置)后指针变为垃圾,当您稍后尝试访问时会导致分段错误

if(input == "O"){
    Oblock myBlock;
}
^^^^ right here myBlock becomes garbage

此外,如果用户输入&#34; t&#34;之前&#34; O&#34;它会导致分段错误,因为它们将尝试访问未初始化的指针。你可能应该看看。