美文网首页
C语言成员变量--栈与堆

C语言成员变量--栈与堆

作者: Unclezs | 来源:发表于2019-04-06 17:44 被阅读0次

一、写在前面

最近学数据结构打算重新学一遍c语言,c语言函数返回值不像是java一样,java在定义一个成员变量后给其赋值,直接返回还是能拿到他的值,c却不一样了,成员变量放在栈内存中,栈内存中的成员变量会在方法执行后会释放,所以在成员变量赋值后返回是拿不到数据的

二、栈中的成员变量

1.不能取得值1

例子

看看这个例子

char * testJB()
{
    char a='H';
    return &a;
}
void main()
{
    char p=testJB();
    putchar(p);
}

这个打印的时候你会发现没看到想要的'H'

分析

当testJB执行完成后,a执行的栈内存区域将自动被释放,这时候再返回a的地址已经拿不到数据了

2.不能取得值2

例子
char * test()
{
    char arr[]="hello world";
    return arr;
}
void main()
{
    char *p=test();
    puts(p);
}

运行结果:乱码输出;

分析
char arr[]="hello world";

内存过程:
首先将“hello world” 放入常量区,然后再把其重常量区拷贝到arr的栈内存中,函数执行完成后,arr的栈内存被自动释放,返回的arr首地址也拿不到数据了;

二、堆内存

1.可以取得值1

例子
char * test()
{
    char *p = malloc(sizeof(char)*10);
    *p = "hello word";
    return p;
}
void main()
{
    char *p=test();
    puts(p);
    free(p);
}

运行结果:hello word;

分析:

malloc 函数是在堆内存中开辟一块空间,并且不会自动释放,需要用完后手动释放;
因此,当函数执行完成后,堆内存不被释放,返回首地址仍然可以取得数据,注意用完后手动释放;

2.不可取得值1

例子
void test(char *num)
{
    num = malloc(sizeof(char) * 10);
    num="hello word";
}
void main()
{
    char *p=NULL;
    testCY(p);
    puts(p);
}

运行结果:报错;

分析:

test函数中的num指针和main函数中的p指针不是同一个指针,因为形参也可以看作成员变量;在test函数开辟的空间是给num指针开辟的,而不是给p指针开辟的,这时候的p指针一直为NULL;所以这时候报错;

3.可以取得值2

例子
void testCY(char **num)
{
    char *tmp = malloc(100);
    memset(tmp,0,100);
    strcpy(tmp,"hello word");
    *num = tmp;
}
void main()
{
    char *p=NULL;
    testCY(&p);
    puts(p);
    free(p);
}

运行结果:hello word

分析

首先将二级指针num的值赋值为一级指针p的地址值,再创建临时指针tmp,在堆中开辟一块空间,tmp指针指向这块内存,将“hello world”从常量区拷贝到这块内存,再将一级指针p指向tmp指向的地址,这样在函数结束后,二级指针num、一级指针tmp会被销毁,但是一级指针p已经指向了开辟的堆内存;

优化:不需要tmp也可以做到,用num代替tmp;

相关文章

  • C语言成员变量--栈与堆

    一、写在前面 最近学数据结构打算重新学一遍c语言,c语言函数返回值不像是java一样,java在定义一个成员变量后...

  • go-内存机制(1)

    逃逸分析 堆与栈 在go语言中,变量可以存储在栈或者堆之上。如果变量存储在栈之上,那么当这个栈被清理时,对应的栈内...

  • 「C 基础」变量类型

    C 语言内存分配 常量区:存放 常量字符串 堆:存放 对象 栈:存放 局部变量 变量的属性 一、变量的作用域 C ...

  • java se 1.5.2 对象的内存

    栈:方法进栈、压栈运行、运行结束后出栈。局部变量存在方法中。堆:new出的对象,其中包括对象的成员变量和成员方法成...

  • JavaScript变量——栈内存or堆内存

    成员变量在堆,局部变量在栈。堆是线程都可以访问的,而不同线程的栈是无法互相访问的。成员变量可以理解为属性,对象的属...

  • java内存模型

    引用: Java内存模型 java内存模型线程栈:本地变量,堆:对象,对象成员变量,静态成员变量 如果两个线程同时...

  • Java基础篇

    堆栈 栈 存储局部变量 存储方法调用 堆 存储Java对象(成员变量 局部变量 类变量 ->指向的对象都存储在堆内...

  • 慕课网-Linux C语言指针与内存-学习笔记

    Linux C语言指针与内存 工具与原理 指针 数组 字符串 堆内存与栈内存 gdb内存调试工具。 C语言中指针的...

  • 什么是堆栈,以及堆栈的区别

    首先,讨论的堆和栈指的是内存中的“堆区”和“栈区”,OC语言是C语言的超集,所以先了解C语言的内存模型的内存管理会...

  • iOS 堆和栈的区别

    首先,讨论的堆和栈指的是内存中的“堆区”和“栈区”,OC语言是C语言的超集,所以先了解C语言的内存模型的内存管理会...

网友评论

      本文标题:C语言成员变量--栈与堆

      本文链接:https://www.haomeiwen.com/subject/clzriqtx.html