c语言函数中的变量生存期和作用域


#include<stdio.h>
int* creat(void)
{
    int a[3]={100,2,3};
    return a;
}
int main()
{
    int *p;
    p=creat();
    for(int i=0;i<3;i++)
    printf("%d ",p[i]);
}

为什么只有第一项能够正确输出?
还有就是c语言的内存分配有几个区域?分别存储哪些数据?生存期和作用域是怎样的?

int a[3]是局部变量,生存期只在当前函数中,函数返回,a的内存释放,返回的内存地址是一个无效地址,可能被回收给其它程序使用。
如果需要在返回后仍能使用,可以使用malloc()申请内存,如:int* a = malloc(3 * sizeof(int)); 然后返回这个a,这样在main()中可以使用,但要记得使用free()释放这部分内存。像这样:

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

int* creat(void){
    int* a = malloc(3 * sizeof(int)); // 动态分配内存
    a[0] = 100;
    a[1] = 2;
    a[2] = 3;
    return a;
}

int main(){
    int* p;
    p = creat();
    for (int i = 0; i < 3; i++)
        printf("%d ", p[i]);

    free(p); // 释放内存
    return 0;
}

你应该在main函数里定义一个数组来接收creat函数返回的指针(地址),由于你在main函数里定义是指针,所以有问题!
局部变量的范围,就在函数内有效,离开函数就无效了!

creat 函数返回的是 数组a的首地址,数组a的其他元素在creat 函数返回后就无法访问了,等着被系统回收。也就是主函数只有能范围a数组的首地址元素

c语言内存分配可以看看这篇
https://blog.csdn.net/youoran/article/details/10990815

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7755900
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:【C语言进阶】动态内存不知道怎么用?当然是结合柔性数组一起用
  • 你还可以看下c语言参考手册中的 c语言-内存模型与数据竞争
  • 除此之外, 这篇博客: C语言中字符数组只能存放字符串?字符数组和字符串的唯一区别?中的 C语言中字符数组只能存放字符串? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 不是的,C语言中字符数组既可以保存字符,又可以保存字符串。

    字符数组本意就是是指用来存放字符数据的数组。字符数组的元素是字符类型的。字符数组用于存放字符或字符串。

    C语言中字符数组的一般形式为: char 数组名[数据长度] 。例如:char a[10]; a[0]=‘0’; a[1]=’ 1’; a[2]=‘2’; a[3]=‘3’; a[4]=‘4’; a[5]=‘5’; a[6]=’ 6’; a[7]=‘7’; a[8]=‘8’; a[9]=‘9’; 就定义了a为字符数组,包含10个"0"到“9”的字符元素。

    因此,C语言中字符数组不单单只能保存字符串。

  • 您还可以看一下 尹成老师的C语言系列之 链表与相关操作课程中的 指针与结构体补充小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    回答:

    1. 在编写C语言函数时,变量的生存期和作用域问题为什么只有第一项能够正确输出?

    可能是因为第一项的变量生命周期和作用域范围设计得合理,在函数内部定义的局部变量,在退出函数之后就会被系统自动释放,避免了变量被误操作和污染。

    1. C语言中的内存分配一共有几个区域?这些区域分别存储哪些数据?这些数据在不同的区域中的生存期和作用域又是怎样的?

    C语言中的内存分配一共有五个区域,分别为堆区、栈区、全局/静态存储区、常量区和代码区。

    1)堆区:由程序员动态分配和释放,存放在堆区的数据一般有一定的生命周期。使用malloc/free函数进行分配和释放。

    2)栈区:由系统自动分配和释放,存放在栈区的数据在函数运行结束时就被系统自动释放。使用函数进行分配和释放。

    3)全局/静态存储区:存放全局变量和静态变量,它在程序的整个运行周期内都存在,生命周期比栈短,比较稳定。未初始化的静态变量会默认为0,使用static变量可以限制变量的作用域。

    4)常量区:存放常量,以及使用const修饰的变量,这部分数据无法被修改,生命周期和程序运行周期相同。常量区的数据可以共享,所有程序中相同的常量只需要存在一份。

    5)代码区:存放程序的二进制代码和常量,其大小和程序的代码规模相关。程序运行时,代码区的数据被载入内存执行。

    此外,这些数据在不同区域中的生存期和作用域如下: 1)堆区:动态分配的内存需要手动回收,生存期可以较长,作用域在函数内部。 2)栈区:系统自动分配和回收内存,生存期短,只在函数中存在,作用域在函数内部。 3)全局/静态存储区:生命周期和程序运行周期相关,作用域在整个文件中存在。 4)常量区:生命周期和程序运行周期相同,作用域可以在整个程序中共享。 5)代码区:对于存储程序二进制代码和常量,生命周期和作用域与程序的执行周期相关,执行完毕即释放。