为什么 std::unique_lock 更改 std::unique_ptr?

Why std::unique_lock changes std::unique_ptr?

我这里发生了一些奇怪的事情,至少对我来说很奇怪...

我有一个线程函数...

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 指向错误的地址。

为什么地址变了?它是一个 const 指针。 unique_ptr 范围在子线程中位于顶部。等待调用在主线程中。

还有shiftbuf.get()returnsnullptr。就像 unique_ptr shiftbuf 超出了范围,但是这段代码不应该发生这种情况,不是吗?

你能解释一下发生了什么吗?

好的。我想我找到了我的问题。
堆栈上还有另一个数据数组,这个数组被用来越界写入,因为它的索引完全不受控制。 因此 shiftbuf_p 地址可能已更改。
很难找到...没有 -fstack-protector 或 valgrind 检测到原因。