C语言---内存操作及基础知识

程序的内存分段(进程映像):

    程序在使用内存时,把内存进行了分段管理,不同的内存段存储了不同数据,具有不同的功能的特点,大约有几十个内存段,与编程有关的,需要程序员掌握的有以下内存段。

    以下内存段在程序编译完后就确定了,在程序运行期间不会变化,可以使用size ./a.out命令查看:

        text:代码段,C代码会被编译器翻译成二进制指令存储在可执行文件中,当执行程序时,可执行文件的内容会被加载到这块内存中,操作系统就是根据这块内存中存储的指令进行执行的,并且该内存的

内容是只读的,如果代码中强行修改该内存中的代码会发生段错误。

            r-x   读+执行 指令

            r--   只读  常量数据,字符串字面值

        data:全局数据段,存储的是初始化过的全局变量、静态变量。

        bss:静态数据段,存储的是未初始化过的全局变量、静态变量,在main函数执行前该内存段的所有字节会被初始化为0,所以全局变量的默认值是0。

    以下内存段会随着程序的运行而动态变化,可以通过程序对应的/proc/进程号/maps文件查看,查看时要保持程序运行,不能停止。

        heap:堆内存,需要调用内存管理函数分配、释放,需要与指针配合使用。

        stack:栈内存,存储的是局部变量和块变量,空间有限,超过容量上限会出现段错误、栈崩溃。

        使用ulimit -s 可以查看栈内存人容量上限,ulimit -s [size] 可以修改栈内存的容量上限。

getpid( ) 获取当前进程的进程号

ps -aux  查看所有进程的进程号

变量的属性和变量的分类

    变量的属性:

        作用域:变量的使用范围。

        存储位置:变量使用的是那段内存。

        生命周期:变量的定义时间到销毁时间。

    变量的分类:

    全局变量:定义在函数外的变量。

        作用域:整个程序中任何位置都可以使用(可以在函数之间共享)。

        存储位置:如果全局变量初始化则使用data,不初始化则使用bss。

        生命周期:main函数执行前就完成定义,到程序执行结束才释放,整个程序的执行期间不会释放。

全局变量的缺点:

它的名字可能和结构、联合、枚举名、宏名、函数名冲突。

在程序运行期间它不会被释放,浪费内存,尽量少用全局变量。

    局部变量:定义在函数内的变量,它会屏蔽同名的全局变量。

        作用域:从定义的位置开始,到函数结束。

        存储位置:使用的是stack内存段

        生命周期:它所在的函数被调用后,执行变量的定义语句开始,到函数执行结束释放。

   

    块变量:定义在 if、for、while 等语句块内的变量,它会屏蔽同名全局变量和局部变量。

        作用域:只能在它所在的大括号内存使用,出了大括号就不能再使用。

        存储位置:栈内存段

        生命周期:从进入语句块内执行变量的定义语句分配内存,到函数执行结束就回收内存。

void func(void)

{

for(int i=0; i<10; i++)

{

printf("%p\n",&i);

}

int num;

printf("%p\n",&i);           <------------可以定义,可以执行因为i出了for循环就被释放掉了

}

   

局部变量、块变量的优缺点:

1、适用范围受限

2、不能长期保存

3、会随着代码的执行动态的定义、释放,节约内存

全局变量、局部变量、块变量的同名问题:

全局变量、局部变量、块变量可以同名。

局部变量会屏蔽同名的全局变量,块变量会屏蔽同名的全局变量、局部变量。

注意:同一个作用域的标识符才会冲突,不同作用域的标识符不会冲突,最多会屏蔽。

修饰变量的关键字

    auto

        用于定义自动分配、释放内存变量,也就块变量、局部变量,但需要频繁定义局部变量和块变量,所以该关键字不加就代表加,与signed一样,但全局变量不能加该关键字。

        在C++11标准中,该关键字有了新的功能,用于定义自动类型的变量,可以根据初始化数据自动设置变量的类型。

    const

        给变量提供一种保护机制,被它修饰过的变量不能显式修改。

        const int num = 1234;

        num = 6666; // 显式修改是错误的

        *(int*)&num = 6666; // 可以强制修改

        原本使用data内存段的变量,被const修饰后,会使用text内存段,变成真正的常量,强制修改会出现段错误。

    static

      有三个主要功能:限制作用域、改变存储位置、延长生命周期

        把全局变量、函数的作用域由全局限制为只能在它所在的.c文件内使用。

        把局部变量、块变量的存储位置由栈改为bss、data,由于bss和data在程序运行期间无法释放所以局部变量、块变量的生命周期也延长到程序结束才释放,但作用域不变。

        static 修饰的变量也叫静态变量,它们的默认值是0,初始化语句只有第一次执行才有效。

       

    volatile

        关键字的作用就是告诉系统该变量的值是不稳定的、易变的,每次使用该变量时都从内存中读取它的值,也就是不要优化变量的读值过程。

        在代码中第一次使用变量时系统会从内存中读取变量的值,该过程叫读值,默认情况下系统会优化该过程,如果变量的值没有被显式修改,第二次变量时,会直接使用之前读取到的值,而不会重新读取。

        int i = 10;

        int j = i;

        int k = i;

        j和k的值肯定相等,即使在j=

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值