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

  • 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
0
Tingfeng Xian 20 Апр 2019 в 11:39

2 ответа

Лучший ответ

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

2
John Zwinck 20 Апр 2019 в 08:43

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

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

0
rustyx 20 Апр 2019 в 09:01