为什么在堆中调用此函数无法调用cout?

时间:2012-05-14 16:38:52

标签: c++ visual-c++ memory-management heap heap-memory

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

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

3 个答案:

答案 0 :(得分:3)

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

  

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

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

正如其他人所说,这段代码的行为是未定义的,所以具体发生的是具体的。不同的编译器可能表现不同。

答案 1 :(得分:2)

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

如果您想知道特定平台上出现“错误”的情况,我建议您使用调试器逐步查看机器代码。

答案 2 :(得分:1)

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

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

重新编译。跑。享受!