0

我试图调用在堆中分配的函数。经过一些失败的尝试后,我尝试了此网站中的代码:

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 打印数据的函数,那么该代码也不起作用。

4

3 回答 3

3

在您所指的文章中,它指出:

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

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

正如其他人所说,这段代码的行为是未定义的,所以究竟发生了什么是特定于实现的。不同的编译器可能表现不同。

于 2012-05-14T16:42:35.037 回答
2

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

如果您想知道您的特定平台上发生了什么“错误”,我建议使用调试器来单步执行机器代码。

于 2012-05-14T16:41:49.340 回答
1

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

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

重新编译。跑。享受!

于 2012-05-14T17:11:09.630 回答