我在Visual Studio 11开发人员预览版中遇到了一个错误,至少我认为这是一个错误并报告了它,但我很感兴趣是否有人知道解决方法.
当我使用std::thread类创建多个线程时,它会导致应用程序崩溃.有时它抛出异常,有时会导致访问冲突,有时它会起作用.重现错误的代码如下所示:
#include <iostream>
#include <thread>
#include <vector>
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<std::thread*> threads;
for(int i = 0; i < 10; i++)
{
threads.push_back(new std::thread([i]
{
/*std::cout << "thread " << i << std::endl;*/
/* whatever else that is thread safe, or even an empty lambda */
}));
}
for(int i = 0; i < 10; i++)
{
threads[i]->join();
delete threads[i];
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
无论是使用静态CRT库还是动态CRT库都无关紧要(所有这些都是多线程的).
Stacktrace(抛出异常,解锁无主互斥锁):
test.exe!_NMSG_WRITE(int rterrnum) Line 217 …Run Code Online (Sandbox Code Playgroud) 我注意到Visual Studio 2012中出现了一些非常奇怪的事情:定义一对像这样的对象:
auto objp = pair<int, LogMe>();
Run Code Online (Sandbox Code Playgroud)
会不会的Elid一对在VC11的复制/移动,这个调用会打印:
LogMe::LogMe - def.ctor!
LogMe::LogMe - move.ctor!
LogMe::~LogMe - dtor!
Run Code Online (Sandbox Code Playgroud)
也就是说,将创建一个临时对,然后将其移动到objp变量中.(声明pair<...> obj;它只记录默认的ctor)
我单独使用LogMe测试对象进行交叉检查:
cout << "# Construct Object via auto obj = ...\n";
auto obj = LogMe();
# Construct Object via auto obj = ...
LogMe::LogMe - def.ctor!
Run Code Online (Sandbox Code Playgroud)
这里的任务将被删除.
这似乎是VC11特有的,因为在IDEOne(使用gcc 4.8.1)中测试它表明,无关紧要的移动总是在那里被省略.
这里发生了什么? 不能依赖被删除的初始化副本让我感到紧张.
注意:发布与调试版本的测试显示相同的结果.(我原本期望,因为复制省略与MSVC中的优化标志无关.)
要测试的完整源代码(另请参阅ideone链接):
#include "stdafx.h"
#include <iostream>
#include <map>
using namespace std;
struct LogMe {
std::string …Run Code Online (Sandbox Code Playgroud) 我想提高列表和映射的特定用法的性能,其中项目的数量具有100000的硬限制.在这种情况下,STL默认分配器显然不是最佳选择,因为清理所有成千上万的小物件需要很长时间(> 10秒!).更不用说所有其他潜在问题了.
因此,显然要改进这一点,我可以预先分配正确的内存量以包含所有列表/映射节点.到目前为止,我已经能够实现默认分配器的工作版本(通过从std :: allocator_traits派生),它为每个节点使用alloc/free.但我正在努力找出如何修改它以允许"有状态"使用,例如,我非常简单的堆栈:
using namespace std;
class MemPoolStack
{
public:
size_t Size;
size_t Mult;
size_t Total;
size_t Top;
size_t Last;
unique_ptr<byte[]> Data;
unique_ptr<size_t[]> Nexts;
MemPoolStack(size_t size, size_t mult) :
Size(size),
Mult(mult),
Total(size * mult),
Top(0),
Last(0),
Data(new byte[Total]),
Nexts(new size_t[Size])
{
}
size_t& Next(size_t i)
{
return *(Nexts.get() + i);
}
void* Pop()
{
byte* p = nullptr;
if(Top<Size)
{
p = Data.get() + (Top * Mult);
bool last = (Top==Last);
size_t next = last ? Top+1 : …Run Code Online (Sandbox Code Playgroud) 使用Visual C++ 2012编译时如下代码:
namespace
{
void unusedFunction1()
{
}
}
static void unusedFunction2()
{
}
Run Code Online (Sandbox Code Playgroud)
使用 /Wall,编译器报告
警告 C4505:“unusedFunction2”:未引用的本地函数已被删除
对于静态函数usedFunction2()。但它没有报告unusedFunction1()的任何内容。
似乎在匿名命名空间中包含本地函数会抑制未引用的本地函数警告,这对我来说是一个意想不到且令人不快的副作用。
是否有任何方法可以使用 MSVC 或其他 C++ 编译器为匿名命名空间中未引用的本地函数生成警告?
我有一个通过ClickOnce部署的.NET 4.5.2应用程序.它使用Magick.NET库,它需要Visual C++ Redistributable用于Visual Studio 2012.我已经尝试使用2013包,但它仍然需要2012版本才能工作.不幸的是,Visual Studio 2013中可能的先决条件下列出的唯一版本是2013版本.其他版本无处可寻:

如何在Visual Studio 2013中使用ClickOnce应用程序包含Visual C++ 2012运行时库?
编辑:对于另一个版本的Visual Studio 似乎有一个非常类似的问题很少受到关注.
.net clickonce visual-c++-2012 visual-studio-2013 .net-4.5.2
我可以实现类似于以下代码的内容:
#define MODULE base
#if defined (MODULE ## _dll) <-- this should do `#ifdef base_dll`
...
#else
...
#endif
Run Code Online (Sandbox Code Playgroud)
第二行显然是错误的。我能以某种方式做到这一点吗?
谢谢
我需要使用成员声明的条件.
template <bool> struct B;
template <> struct B<true> { void foo(); };
template <> struct B<false> { };
template <typename T>
struct A : public B<is_default_constructible<T>::value> {
using B<is_default_constructible<T>::value>::foo();
void foo(int) {}
};
Run Code Online (Sandbox Code Playgroud)
这显然不起作用,因为B<bool>::foo在一半的情况下没有定义.我怎样才能做到这一点?要在foo(int)旁边B<>::foo()
显示可见A<T>范围?
感谢帮助
我正在编写一个Excel插件,需要wchar_t
为Excel 生成输出(虽然在内部,我们是100%char,实际上限制char为纯ASCII).有一次,我正在使用
swprintf转换:
static wchar_t buffer[ 32369 ];
buffer[0] = swprintf( buffer + 1, sizeof(buffer) - 1, L"#%s!", message );
Run Code Online (Sandbox Code Playgroud)
Excel显示某种CJK字符,但message
(type char const*)是一个以空字符结尾的字符串,其中没有可打印ASCII字符(十六进制值0x20-0x7E).
我在一个小的测试程序中试过这个,用十六进制转换生成的字符串,看起来VC++就message
好像它是一个wchar_t const*(尽管它似乎'\0'正确识别,虽然它是在一个字节上); 这导致了wchar_t像0x6568
(而不是0x0068, 0x0065我期待的)的值.
根据C99标准,对于"%s"说明符,
swprintf应该将字符从char const*
"好像通过重复调用mbrtowc函数[...]"转换.我看到的行为是Visual C++库中的错误,还是全局语言环境中是否存在我必须更改的内容?
(FWIW:当我使用g ++编译和运行我的小测试程序时,我得到了我期望的行为.但是,G ++不是我们的Excel插件的选项,至少目前不是.)
这是我的代码,在WinMain入口点我注册了一个类并尝试创建一个窗口,但CreateWindow()函数总是返回NULL.但是RegisterClass()函数确实成功了.我做错了什么?
#include <Windows.h>
#include <stdio.h>
LRESULT CALLBACK event(HWND, UINT, WPARAM, LPARAM)
{
return 0;
}
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
WNDCLASS wndClass;
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hInstance = hInstance;
wndClass.lpszMenuName = NULL;
wndClass.lpfnWndProc = event;
wndClass.lpszClassName = L"ME";
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.style = CS_HREDRAW | CS_VREDRAW;
int err = RegisterClass(&wndClass);
if (err < 0)
{
MessageBox(NULL, L"Can not …Run Code Online (Sandbox Code Playgroud) 我需要添加Visual C++ 2012 Redestribution (x86)为我所用VS 2016中创建一个安装程序的先决条件,但为了做到这一点我必须创建product.xml沿package.xmlbootsrapper文件夹中.很多帖子建议Bootstrapper Manifest Generator用来生成这些xml文件.但是微软现在已经存档了该工具,因此我没有生成文件的工具.
有什么方法可以Visual C++ 2012 Redestribution (x86)为我的安装程序提供先决条件吗?
visual-c++-2012 ×10
c++ ×8
c++11 ×4
visual-c++ ×4
stl ×2
.net ×1
.net-4.5.2 ×1
allocator ×1
c ×1
clickonce ×1
copy-elision ×1
std-pair ×1