C++ 如何使用指针从不同的函数访问局部变量?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4570366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:47:24  来源:igfitidea点击:

How to access a local variable from a different function using pointers?

c++cpointerslocal-variables

提问by Radek Simko

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?

我究竟做错了什么?“4202656”是什么意思?

Do I have to copy the whole array in the replaceNumberAndPrint()function to be able to access it more than the first time?

我是否必须复制replaceNumberAndPrint()函数中的整个数组才能比第一次访问它更多?

回答by CodesInChaos

myArrayis a local variable and as thus the pointer is only valid until the end of its scope (which is in this case the containing function getArray) is left. If you access it later you get undefined behavior.

myArray是一个局部变量,因此指针仅在其作用域结束(在这种情况下是包含函数getArray)离开时才有效。如果稍后访问它,则会出现未定义的行为。

In practice what happens is that the call to printfoverwrites the part of the stack used by myArrayand it then contains some other data.

在实践中发生的情况是,调用printf覆盖了所使用的堆栈部分,myArray然后它包含了一些其他数据。

To fix your code you need to either declare the array in a scope that lives long enough (the mainfunction 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.

要修复您的代码,您需要在一个生存时间足够长的范围(main您的示例中的函数)中声明数组,或者在堆上分配它。如果在堆上分配它,则需要手动释放它,或者使用 RAII 在 C++ 中释放它。

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 answerfor details on this.

我错过的另一种选择(甚至可能是这里最好的一种,只要数组不是太大)是将数组包装到结构中,从而使其成为值类型。然后返回它会创建一个副本,该副本在函数返回后仍然存在。有关详细信息,请参阅tp1答案

回答by James Gaunt

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 to printf then overwrites this by pushing values onto the stack during its operation which is why the second call to printf displays something different.

当您在 replaceNumberAndPrint 函数中访问数组时,结果未定义。它似乎第一次工作的事实只是一个幸运的巧合。可能您指向的内存位置在堆栈上未分配,并且仍然为第一次调用正确设置,但是对 printf 的调用然后通过在其操作期间将值压入堆栈来覆盖它,这就是为什么第二次调用 printf 显示某些内容的原因不同的。

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).

您需要将数组数据存储在堆上并传递一个指针,或者在保留在范围内的变量中(例如全局或主函数内的某个范围)。

回答by James Gaunt

Try something like that. The way you do it "kills" myArraycause if it locally defined.

尝试这样的事情。myArray如果它是本地定义的,那么您执行此操作的方式会“杀死”原因。

#include <stdio.h>
#include <stdlib.h>

void replaceNumberAndPrint(int * array) {
 printf("%i\n", array[0]);
 printf("%i\n", array[1]);
 printf("%i\n" , array[2]);
 free(array);
}

int * getArray() {
 int * myArray = malloc(sizeof(int) * 3);
 myArray[0] = 4;
 myArray[1] = 64;
 myArray[2] = 23;
 //{4, 65, 23};
 return myArray;
}

int main() {
 replaceNumberAndPrint(getArray());
}

More : http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/

更多:http: //www.cplusplus.com/reference/clibrary/cstdlib/malloc/

Edit:As Comments correctly pointed out: A better way to do it would be that :

编辑:正如评论正确指出的那样:更好的方法是:

#include <stdio.h>
#include <stdlib.h>

void replaceNumberAndPrint(int * array) {
    if(!array)
        return;

    printf("%i\n", array[0]);
    printf("%i\n", array[1]);
    printf("%i\n" , array[2]);
}

int * createArray() {
    int * myArray = malloc(sizeof(int) * 3);

    if(!myArray)
        return 0;

    myArray[0] = 4;
    myArray[1] = 64;
    myArray[2] = 23;
    return myArray;
}

int main() {
    int * array = createArray();
    if(array)
    {
        replaceNumberAndPrint(array);
        free(array);
    }
    return 0;
}

回答by jweyrich

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 mallocor new. Example:

您需要使用mallocor动态分配它(在堆上)new。例子:

int *create_array(void) {
    int *array = malloc(3 * sizeof(int));
    assert(array != NULL);
    array[0] = 4;
    array[1] = 65;
    array[2] = 23;
    return array;
 }
 void destroy_array(int *array) {
     free(array);
 }
 int main(int argc, char **argv) {
     int *array = create_array();
     for (size_t i = 0; i < 3; ++i)
         printf("%d\n", array[i]);
     destroy_array(array);
     return 0;
 }

Alternatively, you can declare the array as static, keeping in mind the semantics are different. Example:

或者,您可以将数组声明为静态,记住语义是不同的。例子:

int *get_array(void) {
    static int array[] = { 4, 65, 23 };
    return array;
 }
 int main(int argc, char **argv) {
     int *array = get_array();
     for (size_t i = 0; i < 3; ++i)
         printf("%d\n", array[i]);
     return 0;
 }

If you don't know what staticmeans, read this question & answer.

如果您不知道什么static意思,请阅读此问答

回答by tp1

Right way to do this is as follows:

正确的做法如下:

struct Arr {
   int array[3];
};
Arr get_array() {
   Arr a;
   a.array[0] = 4;
   a.array[1] = 65;
   a.array[2] = 23;
   return a;
}
int main(int argc, char **argv) {
   Arr a = get_array();
   for(size_t i=0; i<3; i++)
       printf("%d\n", a.array[i]);
   return 0;
}

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.

要理解为什么需要这样做,您需要知道 sizeof(array) 是如何工作的。C(以及 C++)尽量避免复制数组,而您需要 struct 来超越它。为什么需要复制是因为作用域——get_array() 函数的作用域消失了,该作用域中仍然需要的每个值都需要复制到调用作用域。

回答by Prasoon Saurav

Your code invokes Undefined Behaviour because myArraygoes out of scope as soon as getArray()returns and any attempt to use(dereference) the dangling pointer is UB.

您的代码调用未定义行为,因为myArray一旦getArray()返回就超出范围,并且任何使用(取消引用)悬空指针的尝试都是 UB。

回答by John Pickup

myArray goes out of scope as soon as you leave getArray. You need to allocate space for it on the heap instead.

一旦离开 getArray,myArray 就会超出范围。您需要在堆上为它分配空间。

回答by Galik

C++ solution:

C++解决方案:

"May I have any access to a local variable in a different function? If so, how?"

“我可以访问不同函数中的局部变量吗?如果可以,如何访问?”

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 containerlike a std::array(fixed size) or a std::vector(dynamic size).

C++处理返回阵列的方法是在一个管理这些容器的std ::阵列(固定大小)或标准::矢量(动态大小)。

Eg:

例如:

void replaceNumberAndPrint(const std::array<int, 3>& array) {
    printf("%i\n", array[0]);
    printf("%i\n", array[1]);
    printf("%i\n", array[2]);
}

std::array<int, 3> getArray() {
    std::array<int, 3> myArray = {4, 65, 23};
    return myArray;
}

In the second function the returned value is optimized by the compiler so you don't pay the price of actually copying the array.

在第二个函数中,返回值由编译器优化,因此您无需支付实际复制数组的代价。

回答by aquib

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.

在这段代码中,您使用了指向局部对象的指针,但是当函数返回时,所有局部变量都超出了作用域。如果您将分配内存(使用malloc()函数进行分配),则不会丢失或覆盖任何数据。

int* getArray(int size) {
    int *myArray = (int*)malloc(size*sizeof(int));
    myArray[0] = 4;
    myArray[1] = 65;
    myArray[2] = 23;
    return myArray;
}

int main() {
    int i;
    int *vector = getArray(3);
    for(i=0;i<3;i++)
    {
        printf("%i\n",vector[i]);
    }
    getch();
    return 0;
}

This code will print all the array elements and no overwritten will be happened.

此代码将打印所有数组元素,不会发生覆盖。