В C ++ 11 как не передавать аргументы потокам? - PullRequest
0 голосов
/ 20 апреля 2019

Я пытаюсь реализовать следующий код, но прежде чем получить доступ к памяти, соответствующей указателю, я удаляю эту память в основном потоке. Это неопределенное поведение, но вывод нормальный?

  • Apple LLVM версия 10.0.1 (clang-1001.0.46.3)
  • Цель: x86_64-apple-darwin18.2.0
  • Модель резьбы: posix
#include <iostream>
#include <string>
#include <thread>
void newThreadCallback(int *p)
{
    std::cout<<"Inside Thread 1 : p = "<<p<<std::endl;
    std::chrono::milliseconds dura(1500);
    std::this_thread::sleep_for(dura);
    *p = 19;
    std::cout<<"Inside Thread 2 : *p = "<<*p<<std::endl;
}

void startNewThread2()
{
    int *p = new int(10);
    std::cout<<"Inside Main Thread : *p = "<<*p<<std::endl;
    std::cout<<"Inside Main Thread : p = "<<p<<std::endl;
    std::thread t(newThreadCallback, p);
    t.detach();
    delete p;
    p = NULL;
    //std::cout<<"Inside Main Thread : *p = "<<*p<<std::endl;
}

int main()
{
    startNewThread2();
    std::chrono::milliseconds dura(2000);
    std::this_thread::sleep_for(dura);
    return 0;
}

Вывод:

Inside Main Thread : *p = 10
Inside Main Thread : p = 0x7f7f765003a0
Inside Thread 1 : p = 0x7f7f765003a0
Inside Thread 2 : *p = 19

Ответы [ 2 ]

2 голосов
/ 20 апреля 2019

Конечно, это неопределенное поведение.Вы случайно получили правильное поведение в какой-то системе, но вы не всегда можете быть таким «счастливчиком».Простое решение состоит в том, чтобы не передавать необработанные указатели (вы можете использовать unique_ptr здесь).

0 голосов
/ 20 апреля 2019

Вы можете воспроизвести то же поведение без потоков - выделить немного памяти, записать в нее, освободить и затем прочитать из нее - во многих случаях вы прочитаете ожидаемое значение.

Это потому, что во время операции delete область памяти помечается как «свободная», а ее содержимое остается нетронутым. Таким образом, вы будете читать ожидаемое значение из него, пока оно не будет перераспределено и записано в другое место в программе. Нет никакого способа узнать, когда это произойдет, отчасти поэтому неопределенное поведение , т. Е. Не делайте этого.

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