当前位置: 首页 > news >正文

网站备案麻烦吗制作网页的软件

网站备案麻烦吗,制作网页的软件,分类信息网站做推广,萧山网页设计目录 内存分区 运行之前 代码区 全局初始化数据区 、静态数据区 (data) 未初始化数据区(bss(Block Started by Symbol)区) 总结 运行之后 代码区 (text segment) 未初始化数据区(bss) 全局初始化数据区,静态…

目录

内存分区

运行之前

代码区

全局初始化数据区 、静态数据区 (data)

未初始化数据区(bss(Block Started by Symbol)区)

总结

运行之后

代码区 (text segment)

未初始化数据区(bss)

全局初始化数据区,静态数据区(data segment)

栈区(stack)

堆区(heap)


内存分区

运行之前

如果要执行一个C程序,那么第一步需要对这个程序进行编译。

1预处理宏定义展开,头文件展开,条件编译,这里不会检查语法
2编译检查语法,将预处理后的文件编译成汇编文件
3汇编将汇编文件生成目标文件(二进制) .o文件已生成
4链接 将目标文件链接为可执行程序  二进制文件转换可执行文件 类似.ext

当编译完成生成可执行文件之后,我们可以通过linux下的size买了查看一个可执行二进制文件基本情况:

通过上图可以得知,在没有运行程序前,也就是说,程序没有加载到内存前,可执行程序内部已分好3段信息,分别是 代码区(text)  , 数据区(data)  和未初始化数据区(bss) 3个部分(可以把data和bss合起来叫做静态区,或者全局区)

以下是细分:

bss区域放未初始化的数据如: static int a; //未初始化数据。
static int a = 10 ;//这个时候数据放在数据区 data区。

代码区

存放CPU执行的机器质量。通常代码是可以共享的(即另外的执行程序可以调用它),使其可共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。代码通常是只读的,使其只读的原因是防止程序意外的修改他的指令。另外,代码区还规划了局部变量的相关信息。

说白了,代码区,就是放代码的

以上重点
共享:比如我们创建了一个a.exe和a1.exe两个代码是一样然后,第一次点击a.exe ,第二次点击a1.ext其实运行的还是a.exe原因是代码一样,共享

只读:比如我们在开发一个游戏币,创建了游戏币和人名币两个变量,如果是可写的,那么吧游戏币写到人名币里面那这样就是大事故,所以设置成只读。

全局初始化数据区 、静态数据区 (data)

该区包含了在程序中明确被初始化的全局变量,已经初始化的静态变量(包括全局静态变量)和常量数据(字符串常量)

未初始化数据区(bss(Block Started by Symbol)区)

存入的是全局未初始化变量和未初始化静态变量。未初始化数据区的数据在程序开始执行之前被内核初始化未0后者空(NULL)

总结

程序源代码被编译之后主要分成两段: 程序指令(代码区)  和  程序数据(数据区) 。代指码段属于程序指令,而数据域段和bss段属于程序数据

为什么要分开?

程序被加载到内存中之后,可以将数据和代码分别映射到两个内存区域。由于数据区域对进程来说是可读可写的,而指令域对程序来说是只读的,所以区分之后,可以将程序指令区域和数据区域分别设置成可读可写或者只读。这样可以防止程序的有意或者无意被修改

当程序中运行着多个同样的程序的时候,这些程序执行的指令都是一样的,所以只需要内中保存一份程序的指令就可以了,只是每一个程序运行中数据不一样而已,这样可以节省大量的内存。

运行之后

程序在加载到内存前,代码区和全局区(data 和 bss)的大小就是固定的,程序运行期间不能改变。然后,运行可执行程序,操作系统吧物理硬盘程序,加载到内存,除了根据可执行程序的信息分出代码区(text) , 数据区(data) 和未初始化数据区(bss)之外,还额外增加了栈区,堆区

代码区 (text segment)

加载的是可执行文件代码段,所有的可执行代码都加载到代码区,这块内存是不可以在运行期间修改的

案例:

int main() {int a = 1; // 这一行对应的机器指令就存储在代码区return 0;
}

未初始化数据区(bss)

加载的是可执行文件bss段,位置可以分开亦可以紧靠数据段,存储于数据段的数据(全局未初始化,静态未初始化数据)的生命周期未整个程序运行过程。

案例

   int a; // 存储在BSS段,默认值为0static int i; // 局部静态变量,默认值也为0,存储在BSS段

全局初始化数据区,静态数据区(data segment)

加载的是可执行文件数据段,存储于数据段(全局初始化,静态初始化数据,字符常量(只读))的数据的生存周期为整个程序运行过程。

案例

   int a= 10; // 存储在数据段static int i= 20; // 局部静态变量,同样存储在数据段

栈区(stack)

栈是一种先进后出的内存结构,由编译器自动分配释放,存放函数的参数值,返回值,局部变量等。在程序运行过程中实时加载和释放,因此,局部变量的生存周期为申请到释放该段栈空间。

栈的空间是有限的,尽量用完就释放掉

1是第一个进入。

如果1想出来,那要吧4先扔掉,3在扔掉,2在扔掉,才是1

可以认为吃米饭一样,先吃上面的,才能见碗底。

堆区(heap)

堆是一个大容器,它的容量要远远大于栈,但没有栈那样的先进后出的顺序。用于动态内存分配。堆在内存中位于bss区和栈区之间。一般由程序员分配释放,若程序不释放,程序结束时由操作系统回收

大容量:大容量,到底有多大,要看机器有多好,看机器

分配:使用malloc函数分配

释放:使用free函数释放 ,如果不释放程序会在系统结束后回收 注意,一定要手动释放

生命周期

类型作用域生命周期存储位置
auto变量一对{}内当前函数栈区
static局部变量一对{}内整个程序运行期初始化在data段,未初始化在BSS段
extern变量整个程序整个程序运行期初始化在data段,未初始化在BSS段
static全局变量当前文件整个程序运行期初始化在data段,未初始化在BSS段
extern函数整个程序整个程序运行期代码区
static函数当前文件整个程序运行期代码区
register变量一对{}内当前函数运行时存储在CPU寄存器
字符串常量当前文件整个程序运行期data段

栈 注意事项

案例1

int* func() {int a = 10;return &a;
}void test01() 
{int* p = func();printf("p = %d\n",p);
}

运行结果:

从上面结果来看,不是我们预期的结果,我们预期结果是 p = 10

为什么是这样?

首先我们来看func函数,函数定义的是int a = 10, 函数最终返回了a的地址,所以a在栈区的值已经释放了,我们没有去操作这一块内存。

案例2

char * getMyName()
{char myName[] = "达帮主";return &myName;
}void test02()
{char* p = getMyName();printf("my name p = %s\n",p);
}

运行结果:

问题与案例1一样,也是释放了,不要在意结果。

栈的释放过程

从上面图中可以看出,当getMyName方法运行完成之后,常量区的内容是会被释放的,放回p收到的只是地址。所以上面案例2是乱码,内容被释放,我们根本不知道是上面东西。

总结

不要返回局部变量地址,局部变量在函数执行之后就释放了,我们没有权限去操作释放后的内存。

堆 注意事项

案例1

int* getSpace() {//手动分配堆空间int *p = malloc(sizeof(int)*5);if (p == NULL) {return 0;}for (int i = 0; i < 5; i++) {p[i] = 1000 + i;}return p;
}void test01() {int* p = getSpace();for (int i = 0; i < 5; i++){printf("p:%d \n",p[i]);}//手动释放堆空间free(p);p = NULL; //防止野指针
}int main() 
{test01();printf("\n\n");system("pause");return EXIT_SUCCESS;
}

运行结果:

从上面代码来看我们使用了malloc来分配空间,分配的内存是存在堆中,所以数据没释放是一直存在的。

案例2

void getMyName(char *pp) 
{//分配内存char * temp = malloc(sizeof(char)*50);if (temp == NULL) {return;}memset(temp,0,50);//赋值strcpy_s(temp,50,"达帮主");pp = temp;
}void test02()
{char* p = NULL;getMyName(p);printf("%s\n",p);
}

运行结果

上面的原因是因为同级指针通过函数参数是无法修饰到p的,所以我们要在函数参数写二级指针。

如果主调函数中没有给指针分配内存,被调函数用同级指针是修饰不到主调函数中的指针的。

看下面案例

void getMyName(char **pp) 
{//分配内存char * temp = malloc(sizeof(char)*50);if (temp == NULL) {return;}memset(temp,0,50);//赋值strcpy_s(temp,50,"达帮主");*pp = temp;
}void test02()
{char* p = NULL;getMyName(&p);printf("%s\n",p);
}

运行结果:

上下的区别是加入二级指针,以及传的是地址,最后吧分配的内存修饰给二级指针

流程图

总结

在理解C内存分区时,常会碰到术语:数据区,堆,栈,静态区,常量区,全局区,字符串常量区,文字常量区,代码区等等。在这里,尝试捋清楚以上分区的关系。

  •  数据区包括:堆,栈,全局/静态存储区。
  • 全局/静态存储区包括:常量区,全局区、静态区。
  • 常量区包括:字符串常量区、常变量区。
  • 代码区:存放程序编译后的二进制代码,不可寻址区。


可以说,C/C++内存分区其实只有两个,即代码区和数据区

http://www.zhongyajixie.com/news/13309.html

相关文章:

  • 做视频网站需要执照吗百度的特点和优势
  • 做网站服务器空间网络推广竞价是什么
  • 个人经营性网站备案怎么学seo基础
  • 桑拿网站只做推广软文范例
  • wordpress生成海报图片插件seo网站营销推广公司
  • 旅游网站繁体asp宣传软文怎么写
  • 甘肃营销型网站建设吉安seo网站快速排名
  • 网站建设网站免费软件测试培训
  • web前端如何仿网站2022适合小学生的简短新闻
  • 内网 wordpress慢seo优化厂商
  • 今日头条新闻头条百度seo技术优化
  • 无锡seo公司网站seo诊断服务
  • wordpress怎样建立多站点百度手机快速排名点击软件
  • 网站建设 小知识关键词生成器 在线
  • 365网站潍坊seo招聘
  • 苹果手机怎么做微电影网站吗网络营销的含义是什么
  • 做网站如何选择数据源千锋教育的真实性
  • 2017做网站挣钱b站推广2023
  • 怎样建设公司网站百度关键词优化多久上首页
  • 万网网站需要的步骤网络营销就业方向和前景
  • 网站建设模版百度竞价点击价格
  • flash做的网站营销存在的问题及改进
  • 中铁建设集团门户网站推广免费
  • 做网站首页有什么应用商店下载
  • 敬请期待哦我赢网seo优化网站
  • 杭州网站设计开发品牌网站建设哪家好
  • 珠海企业网站制作公司引流推广怎么做
  • 做管理信息的网站全案网络推广公司
  • 西安医疗网站建设上海网站排名seo公司
  • 手机网站开发怎么样今日新闻最新消息