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

Rad*_*mko 50 c c++ pointers local-variables

我可以在不同的函数中访问局部变量吗?如果是这样,怎么样?

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());
}
Run Code Online (Sandbox Code Playgroud)

上面一段代码的输出:

65
4202656
Run Code Online (Sandbox Code Playgroud)

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

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

Cod*_*aos 57

myArray是一个局部变量,因此指针只有在其范围结束时(在这种情况下是包含函数getArray)才有效.如果您以后访问它,您将获得未定义的行为.

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

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

我错过了一个替代方案(可能是这里最好的一个,只要数组不是太大)就是将数组包装成一个结构,从而使它成为一个值类型.然后返回它会创建一个在函数返回后幸存的副本.有关详细信息,请参阅tp1答案.

  • 我会说推荐`static`作为这个问题的解决方案是有害的,从来没有帮助.对于新手来说,它变成了一个公式化的创可贴来代替真正理解问题和编写正确的代码,后来当别人继承新手的代码时,他们会对所有无意义的静态变量感到震惊. (5认同)
  • 使其静态具有完全不同的语义,尤其是在多线程应用程序中,除非数组的内容是常量. (3认同)
  • 当然,但这是一种解决问题的方法,应该指出,对吧? (3认同)
  • 或者你可以声明它是静态的. (2认同)
  • 指出它当然是有用的,但你也需要指出缺点,所以你的第一个评论有点不完整. (2认同)

Jam*_*unt 18

一旦超出范围,您就无法访问本地变量.这就是本地变量的含义.

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

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


小智 8

尝试类似的东西.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());
}
Run Code Online (Sandbox Code Playgroud)

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

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然这很有效但很难看.您应该更改函数名称(`getArray` =>`createArray`)以更好地描述它们的行为.并且使用`replaceNumberAndPrint`删除源数组对我来说似乎不是一个好主意.我宁愿将删除和打印分成两个不同的功能. (2认同)
  • @Muggen:你不喜欢`array [i]`而不是`*(array + i)`? (2认同)