Почему std :: unique_lock меняет std :: unique_ptr? - PullRequest
0 голосов
/ 14 апреля 2020

У меня здесь что-то странное происходит, по крайней мере для меня это странно ...

У меня есть функция потока с ...

void run(std::mutex &mtx, std::condition_variable &cv)
{
    std::unique_ptr<float[]> shiftbuf(new float[SHIFTBUF_SIZE]);
    float *const shiftbuf_p = shiftbuf.get();

    for (;;)
    {
        *(shiftbuf_p + SHIFTBUF_SIZE - 1) = 100.f;
        std::unique_lock<std::mutex> lck(mtx);
        cv.notify_all();
    }
}

В основном что-то как ...

std::mutex mtx;
std::condition_variable cv;
std::thread th(run, std::ref(mtx), std::ref(cv));

std::unique_lock<std::mutex> lck(mtx);

cv.wait(lck);

Когда я отлаживаю код и смотрю shiftbuf_p адрес меняется на lck?!

Thread 18 "..." hit Hardware watchpoint 4: shiftbuf_p

Old value = (float * const) 0x7fffd8000b10
New value = (float * const) 0x7fffd8000b01
run (mtx=..., cv_second=..., amplitude_data=..., tm=...)
    at ....cpp:132
132             std::unique_lock<std::mutex> lck(mtx);
(gdb) c
Continuing.

Thread 18 "..." hit Hardware watchpoint 4: shiftbuf_p

Old value = (float * const) 0x7fffd8000b01
New value = (float * const) 0x7fffd8000001
run (mtx=..., cv_second=..., amplitude_data=..., tm=...)
    at ....cpp:132
132             std::unique_lock<std::mutex> lck(mtx);
(gdb) c
Continuing.

Thread 18 "..." hit Hardware watchpoint 5: shiftbuf_p

Old value = (float * const) 0x7fffd8000001
New value = (float * const) 0x7fff00000001
run (mtx=..., cv_second=..., amplitude_data=..., tm=...)
    at ....cpp:132
132             std::unique_lock<std::mutex> lck(mtx);
(gdb) c
Continuing.

Thread 18 "..." received signal SIGSEGV, Segmentation fault.

И это никогда не переключается обратно на правильный адрес отправителя. Когда run() продолжает shiftbuf_p указывает на неправильный адрес.

Почему адрес меняется? Это константный указатель . Область unique_ptr является верхней в дочернем потоке. Ожидание вызова в основном потоке.

Но также shiftbuf.get() возвращает nullptr. Как unique_ptr shiftbuf вышел из области видимости, но это не должно происходить с этим кодом, не так ли?

Можете ли вы объяснить, что происходит?

1 Ответ

0 голосов
/ 15 апреля 2020

Хорошо. Я думаю, что нашел свою проблему.
В стеке был другой массив данных, и этот использовался для записи его границ, потому что его индекс был полностью неуправляемым. И поэтому адрес shiftbuf_p может быть изменен.
Трудно найти ... -fstack-protector или valgrind не обнаружили причину.

...