为什么 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 检测到原因。
我这里发生了一些奇怪的事情,至少对我来说很奇怪...
我有一个线程函数...
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 检测到原因。