Я пытаюсь понять управление памятью в C ++. Насколько я знаю, объекты в стеке гарантированно живут (если стек теперь переполнен) только в текущем блоке кода. Если я вызываю функцию из этого блока и передаю ссылку на объект стека на эту функцию, она должна работать, потому что вызывающий блок еще жив.
Что происходит с объектами стека, если я запускаю новый поток из текущего блока кода? Насколько я понимаю, этот блок считается законченным.
Проблема в том, что переменные стека живут некоторое время после завершения блока, поэтому я не могу понять, гарантированно они живут или нет.
Здесь у меня есть код. Он компилируется и работает хорошо, но я полагаю, что он не гарантированно работает.
main.h:
#include <QObject>
#include <QThread>
#ifndef MAIN_H
#define MAIN_H
class MyThread : public QThread
{
Q_OBJECT
virtual void run();
signals:
void returnVar(int *aPtr, int *bPtr);
public:
int *a;
int *b;
};
class MyClass : public QObject
{
Q_OBJECT
int a; // Is it considered stack or global?
void someFunc(int *aPtr, int *bPtr);
MyThread thread; // Is it OK to create thread objects like this or should I use heap only?
public:
MyClass();
public slots:
void varAdded(int *aPtr, int *bPtr);
};
#endif // MAIN_H
.cpp файл:
#include <QCoreApplication>
#include <QDebug>
#include "main.h"
void MyThread::run()
{
qDebug() << "A in thread: " << *a << ", B in thread: " << *b;
emit returnVar(a, b);
}
MyClass::MyClass()
{
a = 1;
int b = 2;
someFunc(&a, &b);
//MyThread thread; // If i declare thread here program will crush because thread was destroyed while running
QObject::connect(&thread, SIGNAL(returnVar(int*, int*)), this, SLOT(varAdded(int*, int*)));
thread.a = &a;
thread.b = &b;
// Is current block considered alive when I start a thread?
// As far as I understand it it not alive any more. Am I right?
thread.start();
// If I give this block some time I can create stack thread object in constructor and it will work
//std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
void MyClass::someFunc(int *aPtr, int *bPtr)
{
// As far as I understand these objects will work fine anyway because calling block is alive.
// Am I right?
qDebug() << "A: " << *aPtr << ", B: " << *bPtr;
}
void MyClass::varAdded(int *aPtr, int *bPtr)
{
qDebug() << "A returned from thread: " << *aPtr << ", B returned from thread: " << *bPtr;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyClass myClass;
return a.exec();
}
Мои квестины:
- Являются ли и thread стеком или глобальными объектами?
- Можно ли объявлять объекты потоков так, как я это делал, или я должен создавать их только в куче?
- Гарантируется ли a и b объекты в потоке?
- Гарантируется ли a и b объекты, когда они (их ссылки) возвращаются из потока?
Я ценю любую помощь.