为什么在堆中调用此函数不能调用cout?

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

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)

3 years ago

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

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

重新编译 . 跑 . 请享用!

3 years ago

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

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

std::cout 是全球性的 . 而且我认为字符串文字可能被归类为"constant string variable",尽管文章术语有些不精确 .

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

3 years ago

你在这里依赖于未定义的行为,并期望它能够做到理智 .

如果你想知道你的特定平台上出现什么“错误”,我建议使用调试器来逐步完成机器代码 .