一步一步写算法(之内存)

原文:一步一步写算法(之内存)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

    内存是程序运行的基础。所有正在运行的代码都保存在内存里面。内存需要处理各种各样的数据,包括键盘的数据、鼠标的数据、usb的数据、串口的数据、摄像头的数据,那么这些数据经过程序的处理之后,就要进行输出到串口、屏幕、usb等。

    内存只有一个,但是程序里面的空间有很多种。但是内存中的数据类型只有几种,比如说全局中的数据、堆中的数据、临时堆栈中的数据。那么他们有什么区别呢?我们可以通过代码发现一些问题。

    (1)全局数据

static int value = 100;

void process()
{
	static int number = 10;
}

    大家可以在这里看到,value和number的数据其实都属于全局数据,这里的变量是不随着函数的调用发生变化的。

    (2)堆数据

void process()
{
	char* point = (char*)malloc(100);
	free(point);
}

    这里的point分配的数据就是堆数据,如果没有free操作,那么它的存在也是全局的。只要内存不主动释放,那么这个内存就会以一直存在。

    (3)临时数据

void process()
{
	char name[100] = {0};
	return;
}

    这里的数据都是堆栈内部的数据,一旦process调用结束返回之前,那么name地址指向的内存空间已经被其他函数使用。此时这段内存空间对我们来说已经没有什么意义了。所以,不管在函数里面用了多少空间,如果你想在函数返回之前继续使用里面的数据,务必在函数返回前拷贝完毕。

    这篇博客的内容比较简单,主要讲述了内存的一些内容。其实关于内存的东西还很多。这里说明一下只是让大家有一个了解:

    1) 全局数据是我们喜欢使用的类型,用起来比较方便

    2)堆数据是系统给我们安排的空间

    3)堆栈空间只能存在于当时的函数之中,函数返回即失去意义

    

    虽然我们上面这么说,但是这三个概念有的时候也是可以相互迁移的,比如说:

    1) 有的时候,我们为了测试的需要,首先构建一个全局内存池,以后测试的内存都是通过自定义的malloc在内存池中分配的,所以这个时候,堆分配和全局联系在了一起。

                全局内存空间          < =========>  内存池     < =========> 本地空间分配

    2) 如果我们使用的函数空间比较小,那么所有的操作就可以在一个函数内部完成了,那么这时候全局空间和临时堆栈是不是一致的呢

               全局空间   < =============>  本地堆栈

    上面的说法有些绕,但是我们的目的只是想让大家时刻明白:

    a)必须时刻明白我们的数据在哪块空间里面

    b)内存会不会越界

    c)内存会不会泄露

    d)内存访问的数据是否依然有效

    

【预告: 下面的博客开始介绍线性空间的内容】

   

    

    

时间: 2024-10-26 19:05:54

一步一步写算法(之内存)的相关文章

一步一步写算法(之克鲁斯卡尔算法 下)

原文:一步一步写算法(之克鲁斯卡尔算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面在讨论克鲁斯卡尔的算法的时候,我们分析了算法的基本过程.基本数据结构和算法中需要解决的三个问题(排序.判断.合并).今天,我们继续完成剩下部分的内容.合并函数中,我们调用了两个基本函数,find_tree_by_index和delete_mini_tree_from_group,下面给出详细的计算过程. MINI_GENERATE_T

一步一步写算法(之线性结构的处理)

原文:一步一步写算法(之线性结构的处理) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     我们知道,在内存中的空间都是连续的.也就是说,0x00000001下面的地址必然是0x00000002.所以,空间上是不会出现地址的突变的.那什么数据结构类型是连续内部空间呢,其实就是数组,当然也可以是堆.数组有很多优势,它可以在一段连续空间内保存相同类型的数据,并且对这些数据进行管理.所以从这个意义上说,掌握了数组才能说明你数据结构入门了.

一步一步写算法(之 算法总结)

原文:一步一步写算法(之 算法总结) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]       自10月初编写算法系列的博客以来,陆陆续续以来写了几十篇.按照计划,还有三个部分的内容没有介绍,主要是(Dijkstra算法.二叉平衡树.红黑树).这部分会在后面的博客补充完整.这里主要是做一个总结,有兴趣的朋友可以好好看看,欢迎大家提出宝贵意见.       (1) 排序算法     快速排序           合并排序     堆排序

一步一步写算法(之排序二叉树)

原文:一步一步写算法(之排序二叉树) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前面我们讲过双向链表的数据结构.每一个循环节点有两个指针,一个指向前面一个节点,一个指向后继节点,这样所有的节点像一颗颗珍珠一样被一根线穿在了一起.然而今天我们讨论的数据结构却有一点不同,它有三个节点.它是这样定义的: typedef struct _TREE_NODE { int data; struct _TREE_NODE* parent;

一步一步写算法(之查找)

原文:一步一步写算法(之查找) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     无论是数据库,还是普通的ERP系统,查找功能数据处理的一个基本功能.数据查找并不复杂,但是如何实现数据又快又好地查找呢?前人在实践中积累的一些方法,值得我们好好学些一下.我们假定查找的数据唯一存在,数组中没有重复的数据存在.     (1) 普通的数据查找     设想有一个1M的数据,我们如何在里面找到我们想要的那个数据.此时数据本身没有特征,所以我

一步一步写算法(之prim算法 下)

原文:一步一步写算法(之prim算法 下) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     前两篇博客我们讨论了prim最小生成树的算法,熟悉了基本的流程.基本上来说,我们是按照自上而下的顺序来编写代码的.首先我们搭建一个架构,然后一步一步完成其中的每一个子功能,这样最后构成一个完成prim算法计算过程.     f)将DIR_LINE队列中不符合的数据删除,主要是双节点都已经访问过的DIR_LINE数据. void delete

一步一步写算法(之链表逆转)

原文:一步一步写算法(之链表逆转) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     链表逆转是面试环境中经常遇到的一道题目,也是我们在实际开发中可能会遇到的开发需求.和线性逆转不一样,单向链表的节点需要一个一个进行处理.为了显示两者之间的区别,我们分别对线性内存和链表进行逆转:     (1)普通连续内存数据的反转分析 STATUS normal_revert(int array[], int length) { int* pDa

一步一步写算法(之线性队列)

原文:一步一步写算法(之线性队列) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]     这里的线性结构实际上指的就是连续内存的意思,只不过使用"线性"这个词显得比较专业而已.前面一篇博客介绍了现象结构的处理方法,那么在这个基础之上我们是不是添加一些属性形成一种新的数据结构类型呢?答案是肯定的,队列便是其中的一种.     队列的性质很简单:     (1)队列有头部和尾部     (2)队列从尾部压入数据     (3)队列

一步一步写算法(之线性堆栈)

原文:一步一步写算法(之线性堆栈) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]    前面我们讲到了队列,今天我们接着讨论另外一种数据结构:堆栈.堆栈几乎是程序设计的命脉,没有堆栈就没有函数调用,当然也就没有软件设计.那么堆栈有什么特殊的属性呢?其实,堆栈的属性主要表现在下面两个方面:     (1)堆栈的数据是先入后出     (2)堆栈的长度取决于栈顶的高度     那么,作为连续内存类型的堆栈应该怎么设计呢?大家可以自己先试一下