首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >调用getchar更改程序的行为

调用getchar更改程序的行为
EN

Stack Overflow用户
提问于 2014-04-17 16:58:14
回答 1查看 48关注 0票数 1

下面是一个函数(ReturnArr),用于读取10个整数并将它们存储在一个数组中。每增加2,然后返回数组基地址。使用基地址,将打印数组元素(在三个()中)。

代码语言:javascript
复制
#include<stdio.h>
#include<stdlib.h>
int* returnArr()
{
    int arr[10];
    size_t iter = 0;
    while( iter < 10 )
    {
        scanf("%i",arr+iter);
        arr[iter]+=2;
        printf("%i ",arr[iter]);
        iter+=1;
    }
    return arr;
}

void three()
{
    size_t iter = 0;
    int* arr = returnArr();
    //putchar('\n');
    while( iter < 10 )
    {
        printf("%i ",arr[iter]);
        iter+=1;
    }
    return;
}

int main()
{
    //one();
    //two();
    three();
    return 0;
}

理想情况下,程序应该打印垃圾值,因为地址指向在数组遍历之前调用的另一个函数中局部变量的位置。

但是它实际上是在注释putchar函数调用时打印数组元素,当getchar函数调用包含在程序代码中时则是垃圾值。

使用gcc 4.7.2对Debian。

有人能解释一下吗?

-Newbie

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-04-17 17:01:31

程序有未定义的行为:不能返回已在本地分配的数组:

代码语言:javascript
复制
int* returnArr()
{
    int arr[10];
    ...
    return arr; // <<== This is undefined behavior
}

您在调用returnArr之后看到的结果是未定义的:函数返回的内存将被抓取,因此它会被任意事件改变,例如进行加法函数调用。

但是它实际上是在putchar函数调用被注释时打印数组元素,当getchar函数调用包含在程序代码中时则是垃圾值。

如果没有putchar的调用,arr的内存将保持不受干扰,因此您将得到旧值。当您调用putchar时,它的返回地址被放置在堆栈上,就在存储arr的位置。对于未定义的行为来说,这是一个普遍的问题--您不会得到“快速失败”行为,甚至也不会得到保证失败的行为。This answer provides a very nice analogy to what's happening when you return a pointer to local from a function

若要解决此问题,请动态分配数组,并在调用方中释放它,如下所示:

代码语言:javascript
复制
int *arr = malloc(10*sizeof(int)); // Instead of int arr[10];
...
int* arr = returnArr(); // Call the function
...                     // Use arr here, then...
free(arr);              // free it when you are done.
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23139131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档