Объявите указатель в классе, но инициализируйте в другом потоке - PullRequest
2 голосов
/ 24 января 2020

Я объявляю указатель с именем download_webm в основном классе и хочу инициализировать его в своем конструкторе потоков, но каждый раз, когда я пытаюсь сделать это, программа вызывает sh, когда я пытаюсь соединить загрузку WebM и проигрывателя.

int main(int argc, char *argv[])
{


    QApplication app(argc, argv);
    int x;

    DownloadWebm *download_webm;

    MyThread *DownloadWebm_Thread = new  MyThread(download_webm);



    DownloadWebm_Thread->start();


    LinuWebmPlayer *player = new LinuWebmPlayer(argv[1],0);
    QObject::connect(download_webm,SIGNAL(send_packege(Video_Bytes_Package)),player,SLOT(play()));
    player->show();





    return app.exec();
}

Вот мой заголовок темы:

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <qthread.h>
#include <downloadwebm.h>
class MyThread : public QThread
{
    Q_OBJECT

public:
    MyThread(DownloadWebm *);
    MyThread();

protected:
    DownloadWebm **webm;
    void run();
};





#endif // MYTHREAD_H

и CPP:

#include "mythread.h"

MyThread::MyThread()
{

}

MyThread::MyThread(DownloadWebm* we)
{
   webm = &we;
}

void MyThread::run()
{
   *webm = new DownloadWebm("http://trilulilu.de/recstreamingsource?movie=3860","asd");
}

Основной класс видит указатель download_webm неинициализированным!

1 Ответ

4 голосов
/ 24 января 2020
MyThread::MyThread(DownloadWebm* we)

we - это параметр этой функции, а именно конструктор потока. По умолчанию параметры функции передаются по значению . Откуда бы ни пришло we, фактически это we является его копией. Вот что это за we. Копия исходного значения, которое передается в эту функцию. Полностью независим от значения, указанного в вызове функции, который вызывает это.

webm = &we;

Указатель на we сохраняется. Сразу после этого конструктор возвращается. we больше не существует. Это разрушается. Это бывший параметр. Как только вызов функции возвращается, все параметры вызова функции уничтожаются. Этот сохраненный указатель теперь указывает на уничтоженный объект, который больше не существует (помните, что we является копией того, из чего we фактически поступил).

Последующие попытки разыменовать этот указатель приводят к попытке доступа разрушенный объект. Это ваше неопределенное поведение, и cra sh.

В вашем main():

MyThread *DownloadWebm_Thread = new  MyThread(download_webm);

download_webm указатель неинициализирован, поэтому передача его копии в конструктор неопределенное поведение, а также. Для конструктора логически невозможно получить доступ к download_webm, поскольку его параметр является независимой копией этого неинициализированного указателя.

Вы можете передать указатель на download_webm вместо этого:

MyThread *DownloadWebm_Thread = new  MyThread(&download_webm);

И объявление и код конструктора корректируются соответствующим образом.

Вы также можете передать ссылку на download_webm, которая будет более похожа на C ++, если вы ш sh. В этом случае параметр конструктора должен быть объявлен как ссылка на указатель:

MyThread::MyThread(DownloadWebm *&we)

При этом остальная часть существующего кода в основном остается неизменной, в этом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...