理解const的内存分配

理解const的内存分配

1. 基础知识

在C语言例,const的含义是被称为一个不能被改变的普通变量,而在C++中其含义就不尽相同。尤其,目前许多的资料都指出:C++中的const常量,C++编译器都会尽量避免const 常量的内存分配,只有当不得已的时候才会分配具体的内存空间给const变量。

具体什么情况下会分配内存给const变量,目前已经确定的有如下几种情况:

2. 解析const int作为全局变量时的内存分配

只看干巴巴的文字,总有一股难以理解的感觉。为此,决定实际检验下。

有如下代码,通过反汇编以及查看符号表的方式来确定globa_const_int_N的内存分配,同时以global_const_int_N来做对比。

#include <stdio.h>  

int global_int_M = 6;
const int  global_const_int_N = 7;

int main(int argc, char const *argv[])

    int j = global_int_M;
    printf("%d\n",j);
    j     = global_const_int_N;
    printf("%d\n",j);
    return 0;
}

源代码编译:

g++ -g testConst.cpp -o testConst

objdump进行返汇编,并查看符号表

objdump -tS testflush > symc.txt

重点来了,查看符号表,看具体globa_const_int_N和global_int_M的存储位置。

内存分配

这里我们可以很清楚的看到globa_const_int_N和global_int_M是分别存放在.rodata和.data字段的,并且两者的存储空间大小均为4(第四列的0000000000000004代表分配内存大小为4)。

相对应的第一列的0000000000000004和0000000000000004分别代表着对应的内存地址,有兴趣的同学可以打印一下试试。

那么我们再来看一下反汇编得到的main代码:

图中214,215,216行是从global_int_M的存储空间内取出数据然后存储到对应j的存储空间中。

图中223和224行则是将global_const_int_N常量对应的值直接存储到j中!

可以发现,编译器是直接从常量表中取出对应的值存储到j,而不是像global_int_M一样从内存空间中取值。

在这里,我又继续考虑编译器优化会造成的影响。因而在此实验如下:

选择高级的优化等级:

可以看到符号表中已经不存在global_const_int_N。说明其已经不再占有内存了。

查看反汇编代码 :

经过优化过后的汇编代码的易读性已经不如最初。但仍可发现:132行是从global_int_M的存储空间内取出数据然后存储到对应j的存储空间中。,对于137行则是编译器直接将常量值替7存储到j中。

从上我们直到如果对一个全局const int赋值常量的时候,它根据编译器的优化会选择存放在:

  1. 常量表中
  2. 或者编译器直接使用其常量,而不进行存储。

const全局变量内存分配的其他信息

但是const变量的知识显然远远不止这些:

“`cpp
#include

3. 小结

  1. 对于const全局常量,如果初始值是字面值常量,一般会存放在常量表中,编译器在编译过程中就会直接使用常量表中的值来进行语句的操作。如果经过优化,可能会使得直接使用常而放弃存储在常量表中。
  2. 对于编译器没有办法处理的初始值常量,一般就需要分配到内存空间,然后等待运行时进行赋值,取值时候也是从内存空间中提取。
  3. 对于非static 的 const局部变量(如函数中),由于其是局部变量,符号表中将不存在其值,如果需要内存空间也是在栈中进行分配。根据编译器的优化,以及const 变量初始值的不同来决定是否需要分配内存空间。
  4. 对于static 的 const局部变量(如函数中),会根据编译器的优化能力,以及初始值,来决定其是不进行存储,还是直接存储在常量符号表,或者是栈中等等均有可能。
  5. 对于第三点和第四点可以字迹尝试验证。

4. 后记

对于C++这门语言,每次一个很小的知识都能牵扯出来一大堆东西,这也是让人又爱又恨的。本来我想写的是const变量的内存分配,虽然来说,目前仍没有跑题,但是还是不是很完善,除此之外,对于类中const 变量的使用和其内存分配也是非常只得关注的。这些东西留到下次再写吧。

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: string是C++中的字符串类,可以用来存储和操作字符串。而const char *是C语言中的字符串类型,表示一个指向字符数组的指针,常用于函数参数和返回值中。 string可以动态分配内存,可以自动调整大小,可以进行各种字符串操作,比如拼接、查找、替换等。而const char *则需要手动分配内存,并且长度是固定的,不能进行修改操作。 在使用时,string更加方便和安全,可以避免很多内存管理的问题,而const char *则更加轻量级,适合一些简单的字符串操作。 ### 回答2: string和const char *(指向常量的字符指针)都是用于表示字符串的数据类型。 首先,string是C++的标准库中提供的一个数据类型,可以直接使用string类来定义和操作字符串。它是一个非常方便和易于使用的数据类型,提供了丰富的字符串操作功能,如拼接、截取、查找等。 而const char *是C风格的字符串表示方法,需要通过字符指针来指向字符串所在的内存地址。它是一个较为底层的表示方法,使用起来相对麻烦一些。需要手动管理内存,如动态分配和释放内存空间。 string和const char *的区别主要有以下几点: 1. 存储方式:string使用动态内存分配,可以动态扩展和收缩字符串的长度,而const char *需要提前分配好固定长度的内存空间。 2. 内存管理:string类自动管理内存,无需手动释放,而使用const char *的字符串需要手动调用delete来释放内存,以避免内存泄漏。 3. 字符串操作:string类提供了丰富的字符串操作方法,如拼接、复制、查找、替换等,使用方便灵活。而使用const char *则需要借助一些C语言的字符串函数来实现相似的功能。 总体而言,string是C++中推荐使用的字符串表示方法,更加方便、安全和易于理解。而const char *则在一些特定的场景下仍然有其存在的价值,如与C语言的函数交互、操作C库等。 ### 回答3: string是C++标准库中提供的字符串类,而const char *是C语言中用于表示字符串的字符指针。 首先,string是一个封装了char数组的类,它提供了丰富的成员函数,可以方便地对字符串进行操作和管理。它支持动态分配内存,可以根据实际需要自动调整字符串的长度。而const char *只是一个指向字符数组的指针,它没有提供类似的功能,需要手动管理内存。 其次,string可以直接使用“+”操作符进行字符串的拼接,可以直接比较大小并进行排序,还可以使用下标访问和修改字符串的每一个字符。而const char *则需要使用一些库函数来实现类似的功能,如strcat用于字符串拼接,strcmp用于字符串比较,strcpy用于字符串复制等。 此外,string还可以方便地将其他类型的数据转换为字符串,如使用to_string函数将整数转换为字符串。而const char *则需要使用一些库函数或者手动实现转换的过程。 另外,string的使用也更符合面向对象的编程思想,具有更好的可读性和可维护性。而const char *则更接近于C语言的风格,适用于需要与C语言交互的场景。 综上所述,string和const char *在功能和使用上有很大的区别。string提供了更多的功能和便利性,而const char *则更偏向于底层和C语言编程的特点。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值