C++ 可以是局部变量';可以在其范围外访问的内存?
我有以下代码C++ 可以是局部变量';可以在其范围外访问的内存?,c++,memory-management,local-variables,dangling-pointer,C++,Memory Management,Local Variables,Dangling Pointer,我有以下代码 #include <iostream> int * foo() { int a = 5; return &a; } int main() { int* p = foo(); std::cout << *p; *p = 8; std::cout << *p; } #包括 int*foo() { INTA=5; 回报&a; } int main() { int*p=foo(); std::
#include <iostream>
int * foo()
{
int a = 5;
return &a;
}
int main()
{
int* p = foo();
std::cout << *p;
*p = 8;
std::cout << *p;
}
#包括
int*foo()
{
INTA=5;
回报&a;
}
int main()
{
int*p=foo();
std::cout因为存储空间还没有被踩踏。不要指望这种行为。因为存储空间还没有被踩踏。不要指望这种行为。您只是返回了一个内存地址,这是允许的,但可能是一个错误
int * ref () {
int tmp = 100;
return &tmp;
}
int main () {
int * a = ref();
//Up until this point there is defined results
//You can even print the address returned
// but yes probably a bug
cout << *a << endl;//Undefined results
}
是的,如果您尝试取消引用该内存地址,您将有未定义的行为
int * ref () {
int tmp = 100;
return &tmp;
}
int main () {
int * a = ref();
//Up until this point there is defined results
//You can even print the address returned
// but yes probably a bug
cout << *a << endl;//Undefined results
}
int*ref(){
int tmp=100;
返回&tmp;
}
int main(){
int*a=ref();
//直到这一点,才有明确的结果
//您甚至可以打印返回的地址
//但是是的,可能是一只虫子
cout您只是返回一个内存地址,这是允许的,但可能是一个错误
是的,如果您尝试取消引用该内存地址,您将有未定义的行为
int * ref () {
int tmp = 100;
return &tmp;
}
int main () {
int * a = ref();
//Up until this point there is defined results
//You can even print the address returned
// but yes probably a bug
cout << *a << endl;//Undefined results
}
int*ref(){
int tmp=100;
返回&tmp;
}
int main(){
int*a=ref();
//直到这一点,才有明确的结果
//您甚至可以打印返回的地址
//但是是的,可能是一只虫子
难道你编译程序时启用了Optimizer吗?foo()
函数非常简单,可能在生成的代码中被内联或替换了
但我同意Mark B的观点,即结果行为是未定义的。您是否在启用Optimizer的情况下编译了程序?foo()
函数非常简单,可能已在结果代码中内联或替换
<>但是我同意Mark B的结果,行为是不确定的。 C++中,你可以访问任何地址,但是这并不意味着你应该访问。你访问的地址不再有效。它是因为FO返回后没有其他的内存被加扰,但是它可能在很多情况下崩溃。试试你的程序,或者EVE。在编译C++中,你可以访问任何地址,但是这并不意味着你应该访问。你访问的地址不再有效。它是因为FO返回后没有其他的内存被加扰,但是它可能在很多情况下崩溃。尝试分析你的程序,甚至只是编译它。ED,并且……< /P> < P>你从不通过访问无效内存抛出C++异常。你只是举一个引用任意内存位置的一般思想的例子。我可以这样做:
unsigned int q = 123456;
*(double*)(q) = 1.2;
在这里,我只是把123456当作一个double的地址,然后写信给它。可能会发生很多事情:
q
实际上可能是double的有效地址,例如double p;q=&p;
q
可能指向分配内存中的某个地方,而我只是覆盖了其中的8个字节
q
指向分配的内存之外,操作系统的内存管理器向我的程序发送分段故障信号,导致运行时终止它
你中了彩票
按照设置的方式,返回的地址指向内存的有效区域更为合理,因为它可能只在堆栈的下面一点,但它仍然是一个无效的位置,您无法以确定的方式访问它
在正常程序执行过程中,没有人会自动检查内存地址的语义有效性。然而,内存调试器,如<代码> Valgnnd>代码>将很高兴地执行此操作,因此您应该运行程序并通过它来查看错误。 < P>您不会因为访问无效内存而抛出C++异常。ust给出了一个引用任意内存位置的总体思路示例。我可以这样做:
unsigned int q = 123456;
*(double*)(q) = 1.2;
在这里,我只是把123456当作一个double的地址,然后写信给它。可能会发生很多事情:
q
实际上可能是double的有效地址,例如double p;q=&p;
q
可能指向分配内存中的某个地方,而我只是覆盖了其中的8个字节
q
指向分配的内存之外,操作系统的内存管理器向我的程序发送分段故障信号,导致运行时终止它
你中了彩票
按照设置的方式,返回的地址指向内存的有效区域更为合理,因为它可能只在堆栈的下面一点,但它仍然是一个无效的位置,您无法以确定的方式访问它
在正常的程序执行过程中,没有人会自动为您检查内存地址的语义有效性。但是,诸如valgrind
之类的内存调试器会很乐意这样做,因此您应该运行程序并查看错误。在典型的编译器实现中,您可以将代码视为“打印出地址为a的内存块的值”。此外,如果向包含本地int
的函数添加新函数调用,则a
的值(或a
用于指向的内存地址)很有可能这是因为堆栈将被包含不同数据的新帧覆盖
但是,这是一种未定义的行为,您不应该依赖它来工作!在典型的编译器实现中,您可以将代码视为“打印出内存块的值,其中的地址过去由“。此外,如果向包含本地int
的函数添加新函数调用,则a
的值(或a
用于指向的内存地址)很有可能发生更改。这是因为堆栈将被包含不同数据的新帧覆盖
然而,这是未定义的行为,您不应该依赖它来
int * foo()
{
int *x = new int;
*x = 5;
return x;
}
int main()
{
int* p = foo();
std::cout << *p << "\n"; //better to put a new-line in the output, IMO
*p = 8;
std::cout << *p;
delete p;
return 0;
}