我有一个无法轻易复制的例外,但我非常怀疑它发生在 期间VariantClear()。
我有一个函数定义一个变体,然后将其传递给另一个变体,而不VariantInit()先调用它。然后,被调用的函数调用VariantClear()此变体,这可能是异常的来源。
void Func1()
{
VARIANT vData;
//VariantInit(&vData); // no variant clear was done. Will adding this line stop the crash below?
Func2(vData);
}
void Func2(VARIANT& vData)
{
// some code here
VariantClear(&vData); <-- this line crashes, why??
// some code here
}
Run Code Online (Sandbox Code Playgroud)
谁能解释为什么VariantClear()会抛出异常?VariantInit()调用会Func1()阻止此异常的发生吗?
使用编译器资源管理器:
#include <iostream>
#include <memory>
struct test
{
test(int i)
{
std::cout << "test::test("<<i<<")\n";
}
~test()
{
std::cout << "~test()\n";
}
};
template<>
void std::destroy_at(test* p)
{
std::cout<<"std::destroy_at<test>\n";
p->~test();
}
int
main ()
{
auto sp = std::make_shared<test>(3);
return 33;
}
Run Code Online (Sandbox Code Playgroud)
使用带有 gcc x86-64 或 clang x86-64 的 C++20 给出预期输出:
Program returned: 33
test::test(3)
std::destroy_at<test>
~test()
Run Code Online (Sandbox Code Playgroud)
但 x64 msvc v19.32 给出:
Program returned: 33
test::test(3)
~test()
Run Code Online (Sandbox Code Playgroud)
好像 std::destroy_at 在这里没有效果。
这是符合行为、我的误解还是 msvc 不符合或配置错误?
我需要修改一个用 Borland C++ Builder 5 编写的文件,以便在 MS Visual Studio 2022 中使用。其中一个文件大量使用了该dir.h库,据我所知,这是 Builder 独有的 C 库。源文件是可用的,但是它们有很多依赖项,并且正如我所提到的,它们是用 C 编写的。我在互联网上搜索了替代品,不幸的是没有结果。C++ 是否存在类似的库?或者我是否必须使用例如重新编写文件(相当大)std::filesystem?
#include <iostream>
struct Human {
public:
std::string Name;
int* Age;
Human(std::string Name, int Age): Name{Name}, Age{&Age} {}
void Print() {
std::cout << Name << " " << Age << "\n";
}
};
int main() {
Human a = Human("John", 35);
Human b = Human("Brook", 20);
Human c = Human("Lamy", 90);
Human d = Human("Ed", 5);
a.Print();
b.Print();
c.Print();
d.Print();
}
/* Output
John 0x7bfc80
Brook 0x7bfc80
Lamy 0x7bfc80
Ed 0x7bfc80
*/
Run Code Online (Sandbox Code Playgroud)
为什么输出中所有年龄值地址都相同?我如何才能将常量值发送到将获取其地址的对象中?(检查参数化构造函数)常量在内存中没有明确定义的位置,那么这如何可以接受?每次创建对象时变量 int* Age 是否都不会重复?
谢谢你!
我正在开发一个非常小的 C++ 控制台应用程序,仅使用 VSCode 和命令行。(我无法访问我正在使用的计算机上的完整 Visual Studio。)
当发生断言时,我会看到如下对话框:
有没有办法让这些调试信息出现在控制台中,而不是对话框中?
我正在寻找一些示例std::visit,并且我想探索一下以下常见示例代码:
#include <iostream>
#include <variant>
struct Fluid { };
struct LightItem { };
struct HeavyItem { };
struct FragileItem { };
template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
template<class... Ts> overload(Ts...) -> overload<Ts...>; // line not needed in C++20...
int main() {
std::variant<Fluid, LightItem, HeavyItem, FragileItem> package(HeavyItem{});
std::visit(overload{
[](Fluid& ) { std::cout << "fluid\n"; },
[](LightItem& ) { std::cout << "light item\n"; },
[](HeavyItem& ) { std::cout << "heavy item\n"; },
[](FragileItem& ) { std::cout …Run Code Online (Sandbox Code Playgroud) 我目前正在开发一个我打算移植的程序。我可以访问 Windows 和 macOS,并且我希望能够在两者上轻松调试。当错误处理时,我希望在那里有调试中断以使其变得容易(__debugbreak()对于 MSVC)。由于我打算在多个平台上进行开发和测试,因此我想制作一个宏来执行以下操作:
#define DEBUG_BREAK #ifdef DEBUG\
#if _MSC_VER \
__debugbreak(); \
#elif __GNUC__ \
__builtin_trap(); \
#endif \
#endif
Run Code Online (Sandbox Code Playgroud)
DEBUG_BREAK因此,在任何平台上调试时,我可以在任何想要破坏代码的地方编写代码。当我使用这个宏时,我收到错误'#' not expected here。
我发现两个有些相关的问题:
但他们都没有回答我的问题,因为他们试图完成不同的事情。
所以我的问题是:如果允许的话,如何在宏内部使用预处理器 if 语句?如果不可能,我该怎么做才能获得这个损坏的DEBUG_BREAK宏试图执行的相同功能?
注:DEBUG编译时定义,用于调试;编译发布时未定义它。
我已在 Visual Studio 中为我的项目启用了 Address Sanitizer,并成功使用Microsoft Learn中的以下代码对其进行了测试。
#include <stdio.h>
int x[100];
int main() {
printf("Hello!\n");
x[100] = 5; // Boom!
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,清理程序无法在以下代码中找到丢失的删除语句:
struct Object {
int x;
int y;
};
int main() {
Object* obj = new Object();
// Boom!
return 0;
}
Run Code Online (Sandbox Code Playgroud)
查看生成的程序集,我们可以看到 new 运算符确实被调用并且没有被优化掉。以下输出取自 Debug/x86 配置,但对于配置 Debug/x64、Release/x86 和 Release/x64 可以获得类似的输出。
; 6 : int main() {
push ebp
mov ebp, esp
sub esp, 12 ; 0000000cH
mov ecx, OFFSET __62A33F1D_Source@cpp
call @__CheckForDebuggerJustMyCode@4
; 7 : …Run Code Online (Sandbox Code Playgroud) 我想通过以下方式管理 WinAPI 函数对std::unique_ptr:
#include <memory>
int* __stdcall construct(){ return new int{5}; }
void __stdcall destruct(int* v){ delete v; }
int main() {
using Ptr = std::unique_ptr<int, void(&)(int*)>;
Ptr v(construct(), destruct);
}
Run Code Online (Sandbox Code Playgroud)
当我使用 MSVC 19.33 构建 64 位二进制文件时,代码可以正常工作。如果我构建 32 位二进制文件,则会出现错误。
example.cpp
<source>(8): error C2660: 'std::unique_ptr<int,void (__cdecl &)(int *)>::unique_ptr': function does not take 2 arguments
C:/data/msvc/14.33.31631/include\memory(3291): note: see declaration of 'std::unique_ptr<int,void (__cdecl &)(int *)>::unique_ptr'
Compiler returned: 2
Run Code Online (Sandbox Code Playgroud)
__stdcall如果我明确命名in ,它适用于两者std::unique_ptr<int, void(__stdcall&)(int*)>,所以我假设它是函数签名的一部分。
为什么 32 位和 64 位会有这种差异?这是编译器中的错误吗?
我在具有最新更新的 Visual Studio 2022 社区版中使用 Visual C++。在下面的 C++ 代码中,main 创建了 ShowBug 的实例并将其分配给变量 sb。下一行创建 ShowBug 的第二个实例并将其分配给 sb。
在第二行完成之前,它调用析构函数。但是,它不会破坏第一个实例,这正是我认为它会做的,而是破坏了新创建的第二个实例。如果您觉得难以置信,请亲自尝试一下。
那么,我是否在这里遗漏了一些东西(即使用相同的变量来分配新实例是一种糟糕的编程习惯?),或者编译器是否以某种方式做了正确的事情?或者,这是一个编译器错误吗?
// ShowBug.h:
using namespace std;
#include <iostream>
#include <string>
class ShowBug
{
// This class is used to show that the destructor seems to be called for the wrong instance.
//
string S;
int *pArray;
public:
inline ShowBug(const string &s) : S(s)
{
}
inline ~ShowBug()
{
std::cout << "Deleting " + S;
}
};
int main()
{
ShowBug sb = ShowBug("First …Run Code Online (Sandbox Code Playgroud) visual-c++ ×10
c++ ×9
winapi ×2
assembly ×1
c ×1
c++11 ×1
c++builder-5 ×1
clang ×1
destructor ×1
gcc ×1
macros ×1
pointers ×1
std ×1
stdcall ×1
terminal ×1
unique-ptr ×1
variant ×1
windows ×1