【发布时间】:2023-03-30 05:56:01
【问题描述】:
你可以从下面的代码中看到发送给函数的参数没有超过缓冲区大小。
这个问题是随机发生的,而且只发生在调试版本中。
#include <thread>
#include <sstream>
#define BUF_SZ 32
int main()
{
wchar_t src[BUF_SZ]{};
bool running = true;
std::thread th([&] {
for (double g = 0; g < 100000; g += .1)
{
std::wstringstream ws;
ws << g;
wcscpy_s(src, BUF_SZ, ws.str().c_str());
}
running = false;
});
wchar_t dst[BUF_SZ]{};
while (running)
wcscpy_s(dst, src); // assert on "Buffer is too small" randomly
th.join();
return 0;
}
【问题讨论】:
-
评论不用于扩展讨论;这个对话是moved to chat。
-
随着优化调高,我认为您的代码永远不会退出。该运行变量需要设置为 std::atomic。因为它是优化器,所以它不会包含它,因为它在它存在的每个线程中都没有可见的效果。
-
@ZanLynx,程序退出,这是一个简单的SRSW(单读单写)无锁演示。
-
它不仅仅是无锁的,它是布尔无读的。查看 godbolt.org/z/qgsm7r 和汇编输出中的第 249 行。是的,我修改了代码以使用它并对其进行反lambda,如果这是一个词的话。但是,一旦我将 wcscpy_s 定义为内联函数,编译器就会“帮助”删除
running布尔值的“无用”读取。 -
@eihero 对于您的程序目前来说这不是问题,因为您在其他库中执行编译器视图之外的操作。如果该代码对编译器可见,那么它肯定会。在那个godbolt 示例中,您可以看到它正在完成。它只是简单地循环内联 wcscpy_s 函数,而无需读取
running。我只是想在这里为您的未来提供帮助。
标签: c++ windows visual-studio visual-c++