为什么在堆中调用的这个函数不能调用 cout?

Why this function called in the heap can't call cout?

本文关键字:调用 函数 不能 cout 为什么      更新时间:2023-10-16

我试图调用一个在堆中分配的函数。经过几次失败的尝试,我尝试了这个网站上的代码:

http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/85d5da8c-edef-44b0-b42e-deb5f3eb2524

代码完美运行。它编译,运行,给出正确/预期的结果并毫无问题地完成。

但是,如果我尝试在函数中添加类似 std::cout <<"Hello World!"<<std::endl 的东西,将其复制到堆中,然后执行堆函数,它就不起作用。如果那里有cout,它就不起作用,没有cout它就起作用。

我想知道为什么会发生这种情况,以及如何解决这个问题。意识到我这样做的唯一目的是学习,我没有兴趣将其应用于实际用途。

如果我的堆函数调用一个使用 std::cout 打印数据的函数,则该代码也不起作用。

在您引用的文章中,它指出:

仅使用局部变量,不使用全局变量、静态变量和常量字符串变量。

std::cout是全球性的。而且我认为字符串文字可能会被归类为"常量字符串变量",尽管文章术语有些不精确。

正如其他人所说,此代码的行为是未定义的,因此确切地发生的情况是特定于实现的。不同的编译器的行为可能不同。

你在这里依赖于未定义的行为,并期望它做一些理智的事情。

如果你想知道你的特定平台上出了什么"问题",我建议使用调试器来逐步完成机器代码。

您的问题在于,当您将cout代码添加到函数时,您实际上会添加一些函数调用。Microsoft C/C++ 编译器使用一些基本的堆栈帧检查来检测运行时中的问题。这些检查是通过在每次函数调用后调用 __RTC_CheckEsp 函数来执行的。对__RTC_CheckEsp的调用使用 E8 操作码,这意味着相对寻址。当示例函数移动到堆时,对__RTC_CheckEsp的调用变得错误,因为它跳转到错误的位置。

禁用运行时堆栈帧检查(在 Visual Studio 2010 中):项目选项 -> 配置属性 -> C/C++ -> 代码生成 -> 基本运行时检查 ->将其设置为未初始化的变量

重新 编译。跑。享受!