牛客网刷题总结—Day6

1.字节对齐

  为了提高效率,计算机从内存中读取数据时,是按照一定字节量进行读取的。如它固定取32位,也就是4个字节。

  内存对齐时——如果取一个int类型数据,它会一次被计算机读取到——否则就会取两次才能读取到这个数据,效率低

  这是一种空间换时间的做法

 

  结构体的对齐
  1)  结构体内成员按自身长队对齐。自身长度,如char =1, shor =2 , int =4 ,double =8
     所谓自身对齐,指的是该成员的起始位置的内存地址必须是它自身长度的整数倍。如int 只能以0, 4, 8这类的地址开始
  2) 结构体的总大小为结构体的有效对齐值的整数倍
    
    结构体的有效对齐值的确定:
      1) 当未明确指定,以结构体中最长的成员的长度为其有效值。
      2) 当#pragma pack(n)指定时,以n 和结构体中最长的成员的长度中较小者为其值。
      3) 当用 _attribute__((_packed_))指定长度时,强制按照此值为结构体的有效对齐值
  含union时,取union中的最大值
  
2. 类型安全
  c不是类型安全的语言,涉及类型的隐式转换——malloc函数返回的void * 类型 - 故需要显示的类型转换 - int * p = (int *)malloc(sizeof(int));
  c++也不是类型安全的语言,但是相对于c来说更安全

    1)用操作符new来申请内存,严格与对象类型匹配,而malloc是void *;

    2)函数参数为void *的可以改写成模板,模板支持运行时检查参数类型;

    3)使用const代替define来定义常量,具有类型、作用域,而不是简单的文本替换;

    4)使用inline代替define来定义函数,结合函数的重载,在类型安全的前提下可以支持多种类型,如果改写成模板,会更安全;

    5)提供dynamic_cast使得转换过程更安全。

    尽管如此,但如果使用空类型指针或者在两个不同类型指针间做强制转换,很可能引发类型不安全的问题。(由https://www.cnblogs.com/jiangyu0331/p/11714035.html转载)

 

3.无符号整数

  unsigned char i = 1; i -= 3;  i = -2  — 计算机中存储的补码为 ( 0000 0010 )取反 + (0000 0001)  = ( 1111 1110 ) 无符号整数,首位不取符号位 - 即为0xFE - 254

  

4. new delete / malloc free 区别

   void* malloc( size_t size ); void free( void * pointer );

    1)malloc 动态分配内存需要根据对象类型手动指定空间大小,并且需要显示的转换其返回值,开辟内存失败返回NULL,不能初始化

      new 动态分配内存会自动计算对象类型的大小进行分配,无需类型转换,开辟内存失败会抛出异常 bad_alloc,可以给定初始化值 int* p = new int(10);

     2) new/delete 底层是基于malloc 和 free实现的

    3)new/delete是运算符,是可以被重载的;malloc / free 不可以,属于c语言库函数

    4)对于malloc分配内存后,若在使用过程中内存分配不够或太多,这时可以使用realloc函数对其进行扩充或缩小,但是new分配好的内存不能这样被直观简单的改变

    5)对于new/delete若内存分配失败,用户可以指定处理函数或重新制定分配器(new_handler(可以在此处进行扩展)),malloc/free用户是不可以处理的

     6)最后一点对于new/delete与malloc/free申请内存位置说明,malloc我们知道它是在堆上分配内存的

      但new其实不能说是在堆上,C++中,对new申请内存位置有一个抽象概念,它为自由存储区,它可以在堆上,也可以在静态存储区上分配

      这主要取决于operator new实现细节,取决与它在哪里为对象分配空间

 

  

 

posted @ 2020-03-04 14:13  exhina  阅读(152)  评论(0)    收藏  举报