Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;堆栈内存管理问题 我试图理解C++内存管理。据我所知,堆栈上的对象只能在当前代码块中生存(若堆栈现在溢出)。如果我从这个块调用一个函数,并将一个堆栈对象的链接传递给这个函数,它必须工作,因为调用块仍然是活动的_C++_Qt - Fatal编程技术网

C++;堆栈内存管理问题 我试图理解C++内存管理。据我所知,堆栈上的对象只能在当前代码块中生存(若堆栈现在溢出)。如果我从这个块调用一个函数,并将一个堆栈对象的链接传递给这个函数,它必须工作,因为调用块仍然是活动的

C++;堆栈内存管理问题 我试图理解C++内存管理。据我所知,堆栈上的对象只能在当前代码块中生存(若堆栈现在溢出)。如果我从这个块调用一个函数,并将一个堆栈对象的链接传递给这个函数,它必须工作,因为调用块仍然是活动的,c++,qt,C++,Qt,如果从当前代码块启动新线程,堆栈对象会发生什么情况?据我所知,这座大楼已完工 问题是堆栈变量在块完成后会存在一段时间,所以我无法理解它们是否保证存在 这里我有一些代码。它编译得很好,运行得也很好,但我认为它不能保证运行 主要条款h: #include <QObject> #include <QThread> #ifndef MAIN_H #define MAIN_H class MyThread : public QThread { Q_OBJECT

如果从当前代码块启动新线程,堆栈对象会发生什么情况?据我所知,这座大楼已完工


问题是堆栈变量在块完成后会存在一段时间,所以我无法理解它们是否保证存在

这里我有一些代码。它编译得很好,运行得也很好,但我认为它不能保证运行

主要条款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
#包括
#包括
#ifndef MAIN_H
#定义主
类MyThread:publicqthread
{
Q_对象
虚空运行();
信号:
无效返回值(int*aPtr,int*bPtr);
公众:
int*a;
int*b;
};
类MyClass:公共QObject
{
Q_对象
int a;//它被认为是堆栈还是全局的?
void someFunc(int*aPtr,int*bPtr);
MyThread thread;//这样创建线程对象可以吗,还是应该只使用heap?
公众:
MyClass();
公众时段:
添加的无效变量(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();
}
#包括
#包括
#包括“main.h”
void MyThread::run()
{

qDebug()您的
MyClass
有两个实例变量:
int a
MyThread thread
。它们的生存期与
MyClass
的生存期相关联。因此,既然您在
main
函数的堆栈上声明
MyClass
,这两个变量将处于相同的范围内

现在,在
MyClass
的构造函数中,您使用指向变量
a
的指针初始化
MyThread
的字段,如前所示,该变量是整个程序运行时都处于活动状态的堆栈变量,而局部变量
int b
将不再存在(因此指针将无效,取消引用它是一种未定义的行为)只要构造函数完成运行

因此:

  • a
    thread
    是堆栈变量,但由于它们的父级(
    MyClass
    实例)是在
    main
    函数的主作用域中声明的,因此它们在整个程序期间都是有效的
  • 我会这么说,但我绝不是Qt专家(在网络上快速搜索表明,在堆栈上声明Qt对象是安全的,只要您知道它们的生存期)
  • 不,
    b
    将超出范围,因此取消引用指向它的指针将导致UB。您的程序可能会工作,但这样做是不安全的
  • Qt保证的是,作为参数传递给信号的内容会传递给信号的接收器。根据我通过阅读Qt收集的信息,Qt将复制参数(因此,如果参数是类,则将复制构造),并将调用分派给相应的线程(如果订阅是从发出信号的线程以外的线程完成的)。但是,这不会延长(或以任何其他方式控制)通过指针指向的对象的生存期-如果要保证对象完好无损地交付,应使用
    shared_ptr

堆栈对象的寿命与包含它们的函数的寿命一样长,因此,例如,在
main
中定义的堆栈对象在程序持续时间内都有效。“堆栈变量在块完成后的一段时间内有效”--不,它们没有。这就是重点。每个线程都有自己的堆栈。因此每个堆栈上的对象生存期彼此独立。