C语言中的内存管理

时间:2022-12-23 10:40:15

开始陆续的发一下唐老师视频的笔记吧,顺便带一些正冲哥书的的内容。不能一下都发出来,因为内容发多了自己也受不了,而且发的都是学习视频时候的一些笔记,可能会有一些问题不是很清晰。

先说一下C语言中的内存管理。

1.动态内存分配

①原因:程序运行过程中,很有可能需要一些额外的内存空间。
②动态内存从哪里来,还给谁?
  这块是内存是系统专门预留出来的,给程序动态的分配和动态的归还的。
  当free函数的参数为空的时候,那么我们的free什么事都不做了。
  clloc和realloc的用法见截图:

C语言中的内存管理

动态内存是从堆上分配空间的,具体形式以int为例 int *a = (int*)malloc (5*(sizeof(int)))。

2.栈,堆,静态存储区
①没有栈就没有函数,就没有局部变量。函数是依赖于栈的存在而存在的。
  这个栈不是数据结构中的栈,是内存栈。
  后进先出的原则没有改变。
  每一个函数的调用在内存中都会产生活动记录,这个活动记录包括函数的参数和返回地址等等,所以可以说这个活动记录就是在栈上面建立的。

C语言中的内存管理
  按照老唐的话说,一个栈应该包含的有如下数据
  (1)返回地址(子函数ebp在返回ebp的时候应该指向的位置)
  (2)old ebp
  (3)数据(包含函数中的所有数据)(这也是子函数和子函数esp指向的位置)
  栈的增长方式:从栈底一直向上增长。

C语言中的内存管理

C语言中的内存管理

②因为栈的数据在函数执行结束之后就会被释放了,没有传递到函数的外部,所以产生了程序中的堆。
堆中申请的内存在程序主动释放前一直有效。堆空间就是为了动态内存分配而产生的。
堆空间必须要通过申请才可以得到。
堆管理的方法有很多。老唐讲的链表法很清晰。
③程序静态存储区
程序静态存储区在程序运行的时候就已经开辟出来了,同时在程序运行结束的时候释放。
静态程序区的大小在程序编译的时候就已经规定好了。
程序的静态存储区主要用于保存程序运行的全局变量和静态变量。

这三个存储区是程序中所用的绝大数区域。

3.程序的内存布局。
程序中除了栈,堆,静态存储区以外还有其他的存储区么?
可执行程序的布局:
(1)可执行程序的文件头:操作系统来读这个可执行程序的文件头,看一下这个文件头里的信息是不是系统想要的信息。
(2).text段,这里面保存的是主函数和子函数的运行内容。
(3).data段,这里面保存的是申请并且赋值的全局变量,以及申请并且赋值的静态变量。
(4).bss段,这里面保存的是申请但是没有赋值的全局变量,以及申请并没有赋值的静态变量。
通过上面的四个段,没有找到保存申请并且赋值的局部变量的地方也没有申请但是没有赋值的局部变量的地方。因为局部变量是保存在栈空间中的。

程序文件的布局是程序可执行文件的布局,并不是程序执行过程中的布局,堆栈和静态存储区才是程序执行过程(进程)的布局。
text段、data段和bss段在程序运行的时候(进程)会被映射到进程空间中。

栈和堆是要等到程序运行之后由操作系统进行分配的。

这里的栈可以理解成为一个弹性的东西,所以在程序运行的时候映射过来的段和随着栈的行为来行动。
 静态存储区在程序编译的时候就已经开始分配空间了,所以静态存储区在程序运行的时候依然可以对应一部分程序的可执行文件的空间。函数的地址对应的是程序text段中的某个地址。

C语言中的内存管理

C语言中的内存管理

4.野指针通常是因为指针变量保存的值不是一个合法内存地址造成的。
  在C中没有任何手段来判别一个指针是否是野指针。

①局部指针变量没有被初始化。

#include <stdio.h>

	struct student
{
char *name ;
int no ;
};
int main()
{
struct student s;
//这个strcpy函数是把后面指针变量的内存内容赋给前面指针变量的内容。但是前面的指针变量指向的内存并不确定,所以造成了野指针。
strcpy(s.name,"haha");
s.no = 10;
printf ("%s,%d",s.name,s.no);
}

解决办法:

#include <stdio.h>
#include <string.h>
struct student
{
char *name ;
int no ;
};
int main()
{
struct student s;
s.name = (char*)malloc(sizeof(char)*20);
strcpy(s.name,"haha");
s.no = 10;
printf ("%s,%d",s.name,s.no);
}

上面程序少了一个free(s.name).

②指针释放后程序就归还了这片空间,既然归还了那么就不可以再使用这篇空间了。
     使用已经释放后的指针。
  例程:

#include <stdio.h>
#include <string.h>
#include <stdlib.h> int f(char*i)
{
printf ("%s\n",i);
free (i);
}
int main()
{
char *p = (char*)malloc(sizeof(char)*5); strcpy(p, "qwertyui"); f(p);
printf ("%s\n",p);
}

解决办法:

 #include <stdio.h>
#include <string.h>
#include <stdlib.h> int f(char*i)
{
printf ("%s\n",i);
//free (i);
return 0;
} int main()
{
char *p = (char*)malloc(sizeof(char)*10); strcpy(p, "qwertyui"); f(p); printf ("%s\n",p); free (p); return 0;
}

③指针所指向的变量在指针之前被销毁。

5.内存操作中的经典错误
①非法内存操作
②内存分配成功但是并没有初始化

例程;

#include <stdio.h>
int main()
{
char *p = (char *)malloc(10);
printf(p);
free (p);
return 0;
}

③数组越界
④内存泄露
⑤多次释放指针----谁申请谁释放。
⑥使用已经释放的内存。

6.老唐自己的交通规则
①使用malloc之后应该立刻判断返回值是否为空。可以杜绝操作0地址里面的内容,这个地址是为操作系统使用的。

例程:

#include<stdio.h>
int main()
{
int *p = (int*)malloc(sizeof(int)*5); if (p !== NULL)
{
.....
}
free (p);
return 0;
}

②牢记数组长度,防止越界操作。----使用柔性数组。
③动态申请的操作必须和释放操作相匹配。
④free指针以后,被free的指针要赋值为空。

C语言中的内存管理的更多相关文章

  1. c 从语言中的内存管理

    在C里,内存管理是通过专门的函数来实现.另外,为了兼容各种编程语言,操作系统提供的接口通常是 C 语言写成的函数声明(Windows 本身也由C和汇编语言写成). 1 分配内存 malloc 函数 需 ...

  2. Cocos2d-x开发中C&plus;&plus;内存管理

    由于开始并没有介绍C++语言,C++的内存管理当然也没进行任何的说明,为了掌握Cocos2d-x中的内存管理机制,是有必要先了解一些C++内存管理的知识.C++内存管理非常复杂,如果完全地系统地介绍可 ...

  3. objective-C 中的内存管理解说

    初学objectice-C的朋友都有一个困惑,总觉得对objective-C的内存管理机制琢磨不透,程序经常内存泄漏或莫名其妙的崩溃.我在这里总结了自己对objective-C内存管理机制的研究成果和 ...

  4. JNI中的内存管理&lpar;转)

    源:JNI中的内存管理 JNI 编程简介 JNI,Java Native Interface,是 native code 的编程接口.JNI 使 Java 代码程序可以与 native code 交互 ...

  5. javascript中的内存管理和垃圾回收

    前面的话 不管什么程序语言,内存生命周期基本是一致的:首先,分配需要的内存:然后,使用分配到的内存:最后,释放其内存.而对于第三个步骤,何时释放内存及释放哪些变量的内存,则需要使用垃圾回收机制.本文将 ...

  6. Android中的内存管理机制以及正确的使用方式

    概述 从操作系统的角度来说,内存就是一块数据存储区域,属于可被操作系统调度的资源.现代多任务(进程)的操作系统中,内存管理尤为重要,操作系统需要为每一个进程合理的分配内存资源,所以可以从两方面来理解操 ...

  7. C语言之动态内存管理

    C语言之动态内存管理 大纲: 储存器原理 为什么存在动态内存的开辟 malloc() free() calloc() realloc() 常见错误 例题 柔性数组 零(上).存储器原理 之前我们提到了 ...

  8. C语言中动态内存分配的本质是什么?

    摘要:C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配. 本文分享自华为云社区<[云驻共创]C语言中动态内存分配的本质>,作者: G ...

  9. Unity游戏开发中的内存管理&lowbar;资料

    内存是手游的硬伤——Unity游戏Mono内存管理及泄漏http://wetest.qq.com/lab/view/135.html 深入浅出再谈Unity内存泄漏http://wetest.qq.c ...

随机推荐

  1. PHP数组操作

    PHP数组 1.数字索引数组 1.1创建一个数组 php中最常用的两个类型是:数组,字符串.数组也分为两种,一种是数字索引,一种是关键是索引,关键字索引有点像python中字典的意思.数字索引类型的数 ...

  2. MyBatis学习总结&lpar;二&rpar;——使用MyBatis对表执行CRUD操作(转载)

    本文转载自:http://www.cnblogs.com/jpf-java/p/6013540.html 上一篇博文MyBatis学习总结(一)--MyBatis快速入门中我们讲了如何使用Mybati ...

  3. hdu 1082&comma; stack emulation&comma; and how to remove redundancy 分类: hdoj 2015-07-16 02&colon;24 86人阅读 评论&lpar;0&rpar; 收藏

    use fgets, and remove the potential '\n' in the string's last postion. (main point) remove redundanc ...

  4. SQL取出 所有周六 周日的日期

    SQL取出 所有周六 周日的日期 create table SatSun([id] int identity(1,1),[date] datetime,[weekday] char(6)) go de ...

  5. 使用clusterprofile做聚类分析

    library(clusterProfiler ) #cat test.txt gene_symbol EXOSC10ARHGEF10LVWA5B1SRRM1PTAFRCSMD2SH3GLB1GBP6 ...

  6. hadoop2&period;2编程:MRUnit——Test MaxTemperatureMapper

    继承关系1 1. java.lang.Object |__ org.apache.hadoop.mapreduce.JobContext |__org.apache.hadoop.mapreduce. ...

  7. 最近有机会接触到了angularJs

    记点笔记  概念多了 理顺还待时日: 总的来说: 1.ng-src src属性 2.ng-href href属性 3.ng-checked 选中状态 4.ng-selected 被选择状态 5.ng- ...

  8. PHP 4&colon;从Login进一步看到的

    原文:PHP 4:从Login进一步看到的 我们已经在PHP 3:从Login界面谈PHP标记谈到了PHP标记,不过其页面代码有一句 require_once('bookmark_fns.php'); ...

  9. 【Android Developers Training】 69&period; 视图切换的淡入淡出效果

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  10. Python&lowbar;性能测试

    使用pip安装Python扩展库memory_profiler from memory_profiler import profile @profile #修饰器 def isPrime(n): if ...