C语言学习笔记整理

一.sizeof()

1.sizeof的使用:sizeof操作符以字节形式给出了其操作数的存储大小.

sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。

 2.sizeof的结果:sizeof操作符的结果类型是size_t,它在头文件中typedefunsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。

intunsigned int 、short intunsigned short 、long int 、unsigned long 、float、doublelong double类型的sizeof 在ANSI C中没有具体规定,大小依赖于实现,一般可能分别为2222444810

当操作数是指针时,sizeof依赖于编译器。near类指针字节数为2farhuge类指针字节数为4一般Unix的指针字节数为4

当操作数具有数组类型时,其结果是数组的总字节数,联合类型操作数的sizeof是其最大字节成员的字节数。

结构类型操作数的sizeof是这种类型对象的总字节数,包括任何垫补在内.

 

如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。

struct MyStruct

{

char dda;//偏移量为0,满足对齐方式,dda占用1个字节;

double dda1;//下一个可用的地址的偏移量为1,不是sizeof(double)=8

//的倍数,需要补足7个字节才能使偏移量变为8(满足对齐

//方式),因此VC自动填充7个字节,dda1存放在偏移量为8

//的地址上,它占用8个字节。

int type//下一个可用的地址的偏移量为16,是sizeof(int)=4的倍

//数,满足int的对齐方式,所以不需要VC自动填充,type

//放在偏移量为16的地址上,它占用4个字节。

}//所有成员变量都分配了空间,空间总的大小为1+7+8+4=20,不是结构

//的节边界数(即结构中占用最大空间的类型所占用的字节数sizeof

//(double)=8)的倍数,所以需要填充4个字节,以满足结构的大小为

//sizeof(double)=8的倍数

所以该结构总的大小为:sizeof(MyStruc)1+7+8+4+4=24。其中总的有7+4=11个字节是VC自动填充的,没有放任何有意义的东西.

 二.malloc()与 alloc()

 
C语言跟内存分配方式
1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
3从堆上分配,亦称动态内存分配。程序在运行的时候用mallocnew申请任意多少的内存,程序员自己负责在何时用freedelete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多
C语言跟内存申请相关的函数主要有 alloca,calloc,malloc,free,realloc,sbrk等.
其中alloca是向栈申请内存,因此无需释放. malloc分配的内存是位于堆中的,并且没有
初始化内存的内容,因此基本上malloc之后,调用函数memset来初始化这部分的内存空间.
calloc则将初始化这部分的内存,设置为0. 而realloc则对malloc申请的内存进行大小的

调整.申请的内存最终需要通过函数free来释放. sbrk则是增加数据段的大小;

 malloc/calloc/free基本上都是C函数库实现的,跟OS无关.C函数库内部通过一定的
结构来保存当前有多少可用内存.如果程序malloc的大小超出了库里所留存的空间,那么
将首先调用brk系统调用来增加可用空间,然后再分配空间.free时,释放的内存并不立即
返回给os,而是保留在内部结构中. 可以打个比方: brk类似于批发,一次性的向OS申请大
的内存,而malloc等函数则类似于零售,满足程序运行时的要求.这套机制类似于缓冲.
使用这套机制的原因: 系统调用不能支持任意大小的内存分配(有的系统调用只支持固定大小以及其倍数的内存申请,这样的话,对于小内存的分配会造成浪费; 系统调用申请内存代价昂贵,涉及到用户态和核心态的转换.
函数malloc()和calloc()都可以用来分配动态内存空间,但两者稍有区别。    
    malloc()函数有一个参数,即要分配的内存空间的大小:     
    Void *malloc(size_t size);   
    calloc()函数有两个参数,分别为元素的数目和每个元素的大小,这两个参数的乘积就是要分配的内存空间的大小:    
    void *calloc(size_t numElementssize_t sizeOfElement);
    如果调用成功,函数malloc()和calloc()都将返回所分配的内存空间的首地址。
    malloc() 函数和calloc()函数的主要区别是前者不能初始化所分配的内存空间,而后者能。如果由malloc()函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之,如果这部分内存空间曾经被分配、释放和重新分配,则其中可能遗留各种各样的数据。也就是说,使用malloc()函数的程序开始时(内存空间还没有被重新分配)能正常运行,但经过一段时间后(内存空间已被重新分配)可能会出现问题。
    calloc() 函数会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或整数类型的元素分配内存,那么这些元素将保证会被初始化为零;如果你是为指针类型的元素分配内存,那么这些元素通常(但无法保证)会被初始化为空指针;如果你是为实数类型的元素分配内存,那么这些元素可能(只在某些计算机中)会被初始化为浮点型的零。
    malloc() 函数和calloc()函数的另一点区别是calloc()函数会返回一个由某种对象组成的数组,但malloc()函数只返回一个对象。为了明确是为一个数组分配内存空间,有些程序员会选用calloc()函数。但是,除了是否初始化所分配的内存空间这一点之外,绝大多数程序员认 为以下两种函数调用方式没有区别:
    calloc(numElements sizeOfElement);
    malloc(numElements *sizeOfElement)
    需要解释的一点是,理论上(按照ANSIC标准)指针的算术运算只能在一个指定的数组中进行,但是在实践中,即使C编译程序或翻译器遵循这种规定,许多C程序还是冲破了这种限制。因此,尽管malloc()函数并不能返回一个数组,它所分配的内存空间仍然能供一个数组使用(对realloc()函数来说同样如此,尽管它也不能返回一个数组)。
    总之,当你在calloc()函数和malloc()函数之间作选择时,你只需考虑是否要初始化所分配的内存空间,而不用考虑函数是否能返回一个数组。
    当程序运行过程中malloc了,但是没有free的话,会造成内存泄漏.一部分的内存没有
被使用,但是由于没有free,因此系统认为这部分内存还在使用,造成不断的向系统申请内
,是的系统可用内存不断减少.但是,内存泄漏仅仅指程序在运行时,程序退出时,OS将回
收所有的资源.因此,适当的重起一下程序,有时候还是有点作用.
阅读更多
想对作者说点什么? 我来说一句

c语言学习笔记,好东西

2009年05月16日 3KB 下载

C语言学习笔记 C语言学习笔记

2010年10月25日 4.34MB 下载

C语言学习笔记基础完整

2016年08月02日 8KB 下载

C语言学习笔记变量数组指针

2010年08月25日 116KB 下载

没有更多推荐了,返回首页

不良信息举报

C语言学习笔记整理

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭