段、栈与局部变量、全局变量、静态变量

来源:互联网 发布:数控打圈机编程视频 编辑:程序博客网 时间:2024/06/08 08:20

段、栈与局部变量、全局变量、静态变量

很多时候,我们会遇到自己写的程序代码在编译时报一些段地址等相关的错误,主要是对几个概念不清楚,下面通过栗子理解下。

#include <stdio.h>#include <string.h>#include <stdlib.h>int *fun(){        int p = 100;        return &p;}int main(void){        int *p = fun();        printf("%d\n", *p);        return 0;}

上面代码编译时会报错“函数返回变量地址 -Wreturn-local-addr”,有些编译器可能将这个错当成warning,但最终执行文件时,就会出现段错误:Segementation fault.
这是因为函数fun里的变量p是局部变量,局部变量是在栈中分配的,当fun返回,栈里的内容就被释放给别人使用了,所以这里再return这个被释放的地址,自然就不允许了。

#include <stdio.h>#include <string.h>#include <stdlib.h>int *fun(){        int *p = malloc(4);        memset(p, 0, 4);        *p = 100;        return p;}int main(void){        int *p = fun();        printf("%d\n", *p);        return 0;}

这里fun函数里定义了一个局部int类型指针,指向malloc分配的空间,这个程序编译以及执行都不会有问题,可以正常输出100.这里malloc它是在堆上面分配空间,堆上分配不会自动释放,需要用free来手动释放。这也是很多程序中有时忘记这点而导致crash的原因之一。
在第一个程序中,如果我把局部变量声明成static,或者直接把局部变量改成全局变量,第一个程序也可以正常编译与执行,道理是一样的,static, 全局都是在静态空间分配内存,在程序退出才会释放,不同的是在堆上分配空间需要申请空间者自己释放,比如free。

下面再来一个关于结构体的用法:

typedef struct{char *p;}st;st *fun(){static st t;t.p = (char*)malloc(10);memset(t.p, 0, 10);memcpy(t.p, "abcd", 4);return &t;}int main(){st *p;p = malloc(sizeof(st));p=fun();printf("%s\n", p->p);free(p); }
原创粉丝点击