我试图调用在堆中分配的函数。尝试失败后,我尝试了本网站的代码:
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打印数据的函数,那么该代码也不起作用。
答案 0 :(得分:3)
在您所引用的文章中,它指出:
仅使用局部变量,不要使用全局变量,静态变量和常量字符串变量。
但std::cout
是全球性的。我认为字符串文字可能被归类为“常量字符串变量”,尽管文章术语有点不精确。
正如其他人所说,这段代码的行为是未定义的,所以具体发生的是具体的。不同的编译器可能表现不同。
答案 1 :(得分:2)
你在这里依赖于未定义的行为,并希望它能够做一些理智的事情。
如果您想知道特定平台上出现“错误”的情况,我建议您使用调试器逐步查看机器代码。
答案 2 :(得分:1)
您的问题在于,当您向函数添加cout
代码时,您实质上会添加一些函数调用。 Microsoft C / C ++编译器使用一些基本的堆栈帧检查来检测运行时中的问题。通过在每次函数调用后调用__RTC_CheckEsp
函数来执行这些检查。对__RTC_CheckEsp
的调用使用E8操作码,这意味着相对寻址。当示例函数移动到堆时,对__RTC_CheckEsp
的调用会因为跳转到错误的位置而变得错误。
禁用运行时堆栈帧检查(在Visual Studio 2010中):项目选项 - > 配置属性 - > C / C ++ - > 代码生成 - > 基本运行时检查 - >将其设置为未初始化的变量
重新编译。跑。享受!