如何使用指针从不同的函数访问局部变量?
我可以访问不同函数中的局部变量吗?如果是这样,怎么办?
void replaceNumberAndPrint(int array[3]) {
printf("%i\n", array[1]);
printf("%i\n", array[1]);
}
int * getArray() {
int myArray[3] = {4, 65, 23};
return myArray;
}
int main() {
replaceNumberAndPrint(getArray());
}
上面这段代码的输出:
65
4202656
我做错了什么? “4202656”是什么意思?
我是否必须在 replaceNumberAndPrint()
函数中复制整个数组才能比第一次更频繁地访问它?
May I have any access to a local variable in a different function? If so, how?
void replaceNumberAndPrint(int array[3]) {
printf("%i\n", array[1]);
printf("%i\n", array[1]);
}
int * getArray() {
int myArray[3] = {4, 65, 23};
return myArray;
}
int main() {
replaceNumberAndPrint(getArray());
}
The output of the piece of code above:
65
4202656
What am I doing wrong? What does the "4202656" mean?
Do I have to copy the whole array in the replaceNumberAndPrint()
function to be able to access it more than the first time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
myArray
是一个局部变量,因此指针仅在其作用域结束之前有效(在本例中是包含函数getArray
)。如果稍后访问它,您会得到未定义的行为。实际上,对
printf
的调用会覆盖myArray
使用的堆栈部分,然后它包含一些其他数据。要修复代码,您需要在生命周期足够长的作用域中声明数组(示例中的 main 函数),或者在堆上分配它。如果在堆上分配它,则需要手动释放它,或者在 C++ 中使用 RAII 释放它。
我错过的一种替代方法(可能是这里最好的一种,前提是数组不是太大)是将数组包装到结构中,从而使其成为值类型。然后返回它会创建一个在函数返回后仍然存在的副本。请参阅 tp1 的答案 有关详细信息。
myArray
is a local variable and as thus the pointer is only valid until the end of its scope (which is in this case the containing functiongetArray
) is left. If you access it later you get undefined behavior.In practice what happens is that the call to
printf
overwrites the part of the stack used bymyArray
and it then contains some other data.To fix your code you need to either declare the array in a scope that lives long enough (the
main
function in your example) or allocate it on the heap. If you allocate it on the heap you need to free it either manually, or in C++ using RAII.One alternative I missed (probably even the best one here, provided the array is not too big) is to wrap your array into a struct and thus make it a value type. Then returning it creates a copy which survives the function return. See tp1's answer for details on this.
一旦局部变量超出范围,您就无法访问它。这就是局部变量的含义。
当您在
replaceNumberAndPrint
函数中访问数组时,结果是未定义的。它第一次出现的效果只是一个幸运的巧合。您指向的内存位置可能在堆栈上未分配,并且在第一次调用时仍然正确设置,但是对 printf 的调用然后通过在其操作期间将值推入堆栈来覆盖它,这就是为什么第二次调用printf
显示不同的内容。您需要将数组数据存储在堆上并传递指针,或者保留在作用域内的变量(例如全局变量或主函数内的变量)。
You can't access a local variable once it goes out of scope. This is what it means to be a local variable.
When you are accessing the array in the
replaceNumberAndPrint
function the result is undefined. The fact it appears to work first time is just a fortunate coincidence. Probably the memory location you are pointing to is unallocated on the stack and is still correctly set for the first call, but the call toprintf
then overwrites this by pushing values onto the stack during its operation which is why the second call toprintf
displays something different.You need to store the array data on the heap and pass a pointer, or in a variable that remains in scope (e.g. a global or something scoped within the main function).
尝试类似的事情。如果它是本地定义的,那么您执行此操作的方式会“杀死”
myArray
原因。更多: http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/
<强>编辑:正如评论正确指出的那样:更好的方法是:
Try something like that. The way you do it "kills"
myArray
cause if it locally defined.More : http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/
Edit: As Comments correctly pointed out: A better way to do it would be that :
一旦您离开 getArray,myArray 就会超出范围。您需要在堆上为其分配空间。
myArray goes out of scope as soon as you leave getArray. You need to allocate space for it on the heap instead.
您的代码会调用未定义行为,因为一旦
getArray()
返回并且任何尝试使用(取消引用)悬空指针,myArray
就会超出范围是UB。Your code invokes Undefined Behaviour because
myArray
goes out of scope as soon asgetArray()
returns and any attempt to use (dereference) the dangling pointer is UB.局部变量在返回时超出范围,因此无法返回指向局部变量的指针。
您需要使用
malloc
或new
动态分配它(在堆上)。示例:或者,您可以将数组声明为静态,但要记住语义是不同的。示例:
如果您不知道
static
的含义,请阅读 这个问题&回答。Local variables go out of scope upon return, so you can't return a pointer to a local variable.
You need to allocate it dynamically (on the heap), using
malloc
ornew
. Example:Alternatively, you can declare the array as static, keeping in mind the semantics are different. Example:
If you don't know what
static
means, read this question & answer.正确的方法如下:
要理解为什么需要这样做,您需要知道 sizeof(array) 的工作原理。 C(以及 C++)努力避免复制数组,并且您需要结构体来超越它。为什么需要复制是因为作用域—— get_array() 函数的作用域消失了,并且该作用域中仍然需要的每个值都需要复制到调用作用域。
Right way to do this is as follows:
To understand why you need to do this, you need to know how sizeof(array) works. C (and thus c++) tries hard to avoid copying the array, and you need the struct to go past that. Why copying is needed is because of scopes -- the get_array() function's scope disappears and every value still needed from that scope will need to be copied to calling scope.
C++ 解决方案:
答案是否定的,不是在函数结束之后。局部变量此时被销毁。
在
C++
中,处理返回数组的方法是在容器中管理它们,例如std::array (固定大小)或 std::vector(动态大小)。例如:
在第二个函数中,返回值由编译器优化,因此您无需付出实际复制数组的代价。
C++ solution:
The answer is no, not after the function has ended. Local variables are destroyed at that point.
In
C++
the way to deal with returning arrays is to manage them in a container like a std::array (fixed size) or a std::vector (dynamic size).Eg:
In the second function the returned value is optimized by the compiler so you don't pay the price of actually copying the array.
在此代码中,您使用了指向局部对象的指针,但是当函数返回时,所有局部变量都会超出范围。如果您将分配内存(使用
malloc()
函数进行分配),则不会丢失或覆盖任何数据。此代码将打印所有数组元素,并且不会发生覆盖。
In this code you have used pointer to local objects but when a function returns all local variables goes out of scope. If you will allocate memory (using
malloc()
function for allocation) then no data will be lost or overwrite.This code will print all the array elements and no overwritten will be happened.
.c 中的静态 .. 或 .. Global 就可以解决问题;)
然而,程序在整个过程中都会占用这 3 个字节,但是您避免对这样的简单事情进行 malloc (建议对大数组使用 malloc)
另一方面,如果外部函数修改指针,然后内部的“myArray”将被修改,因为它指向它,就是这样
Static ..or.. Global within your .c will do the trick ;)
However the entire time the program will occupy those 3 bytes BUT you avoid doing malloc on simple things like this (malloc recommended for big arrays)
On the other hand if the outside function modify the pointer, then the internal 'myArray' will be modified cause it points to it, that's it