Этот код использует цикл while для получения пользовательского ввода и выполнения соответствующей команды — для краткости я сократил его до 2 команд.
Объект Oblock создан правильно (команда «O»), как и указатель на базовый класс. Похоже, что звонки на оба объекта работают правильно.
Однако после возврата в цикл while указатель на объект оказывается потерянным, а попытка доступа к его элементам (команда «t») вызывает ошибку segfault.
Я включил пример кода ниже — мои вопросы потом.
#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;
}
Спасибо заранее за любые советы! Я искал вопросы, похожие на этот, и не мог найти подходящий для своих нужд.
Tetramino *pBlock
является локальным в своей области. Ты следишь за тем, кто в main
с одним внутри if
,
Также, myBlock
является локальным и будет разрушен — у вас будет свисающий указатель. Вы должны выделить new
(а также delete
…)
Вместо Tetramino *pBlock = &myBlock;
делать pBlock = new Oblock;
когда вы обрабатываете ввод «О» (и обрабатывать delete pBlock
предыдущего).
if (input == "O")
{
Oblock myBlock;
cerr << "0thi: " << myBlock.getValues(0) << endl;
Tetramino *pBlock = &myBlock;
cerr << "0thi: " << pBlock->getValues(0) << endl;
}
Объект с автоматической продолжительностью хранения (обычно называемый локальной функцией-функцией) имеет время жизни, начинающееся после его объявления и заканчивающееся в конце ближайшего окружающего блока }
маркер. Так myBlock
уничтожается в конце этого оператора if и не может быть снова использован.
Также обратите внимание, что вы объявили два разных указателя с именем pBlock
, Назначение внутреннего ничего не делает с более ранним, который все еще не инициализирован.
Отвечая на ваш первый вопрос: да, утверждение
Oblock yblock;
Создает экземпляр Oblock в стеке. Он уничтожается, когда код покидает соответствующий блок, поэтому любые указатели на него становятся недействительными после этого. Чтобы создать объект, который живет так долго, как вы хотите, используйте new
создать объект в куче.
Ваш указатель становится мусором после myBlock
выходит за рамки (где if
оператор закрывается), который будет вызывать ошибку сегментации при попытке доступа к нему позже
if(input == "O"){
Oblock myBlock;
}
^^^^ right here myBlock becomes garbage
Кроме того, если пользователь вводит «t» перед «O», это вызовет ошибку сегментации, поскольку он будет пытаться получить доступ к неинициализированному указателю. Вы, вероятно, должны это посмотреть.