变量大小
数字最终是以二进制存储和表示,八个位(Bit)构成一个字节(Byte)
1 KB = 1024B字节 ,(Kilo Bytes)
1 MB = 1024 KB,(Mega Bytes),经常看到的文件大小
变量的大小:变量在内存里所占的字节数。用操作符sizeof 来测量一个变量或类型的大小。
1、变量在内存中所占的字节称为变量的大小
char型变量表示的范围很小,对应1个字节,可以表示个数,范围从[-128,127]
int型变量表示的范围很大,对应4个字节,可以表示个数
说明:一个类型站的字节越多,表示的范围越大,精度越高。如double占8个字节,而float占4个字节,从而double比float存储更多的信息(存储更多的有效数字)
2、数组变量的大小(数组的大小由元素的类型和个数决定)
int arr[100];
int size=sizeof(arr);
size结果为100×4,即数组arr的大小为400字节
动态分配内存(以字节为单位)
内存:
内存中的每个单元进行编号,从 0 开始依次增长,依次为 0, 1, 2, ..., 1000, 1001,..., 1000000000, 1000000001, ... 把这个编号称为内存单元的地址。那么每个内存单元都有一个地址。在程序运行时,对于每一个变量,它在内存中都对应了几个内存单元。我们把它对应的内存单元的首地址(第一个字节的地址,前8位),称为变量的内存地址,简称为变量的地址。
&a 取得 a 的地址
1、申请一个可以存放300个int的缓存区(buf前加*,int后加*)
int* buffer = (int*) malloc(300);
free(buffer);
①malloc(memory allocation内存分配)函数传入的参数是以字节为单位
②返回值:申请地址的首地址
③malloc都是保留字,不需要头文件支持(错误,因为malloc是函数。只要是函数,都需要头文件支持),对应的头文件是malloc.h 或者 stdlib.h
申请缓冲区,一定是加了*符号的
2、申请一块可以容纳1024个字节的缓冲区,用于存放字符串。将初始字符串设为空字符串
char* buffer = (char*)malloc(1024);
buffer[0] = 0;
字符串为什么用的char,而不是string?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* GetMemory()
{
char* buf = (char*) malloc(128);
strcpy(buf, "helloworld");
return buf;
}
int main()
{
char* str = GetMemory();
printf(str);
free(str);
return 0;
}
输出显示 helloworld,str指向的是一块堆内存,堆内存在free之前总是有效,所以可以被printf使用。
注意 进行动态内存分配时,用的是char*,与下面这种情况区分开:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void GetMemory(char* buf)
{
buf = (char*) malloc(128);
strcpy(buf, "helloworld");
}
int main()
{
char* str = NULL;
GetMemory(str);
printf(str);
free(str);
return 0;
}
GetMemory里修改了变量buf的值,但是buf和str是两个变量,修改buf的值不会影响到str(返回值空void)
与下面情况区分开
#include <stdio.h>
#include <string.h>
void test(int a)
{
a = a * a;
}
int main()
{
int a = 10;
test(a);
printf("a: %d \n", a);
getchar();
return 0;
}
无论子函数中是什么操作,最后的输出值都是10,子函数中关于a的计算不会影响到main中的a值
3、当变量的体积在1K以上时,应考虑在堆上分配内存
数组arr体积太大,不适合定义在函数内。改成malloc/free实现。一般地,当变量的体积在1K以上时,应考虑在堆上分配内存。
int test()
{
int size = 100000;
int* arr = (int*) malloc ( size * sizeof(int));
for(int i=0; i<size; i++)
{
arr[i] = i;
}
free(arr);
}
4、内存的泄露
程序长期运行时就需要格外关注 free内存 的问题,当程序申请的内存积累的越来越多是可能导致系统为内存可用,即内存泄露
在任务管理器中能观察一个进程的内存使用量,这个数字不能一直递增
内存填充
1、memset函数
memse(数组名,val,n)将内存存储数组的n个字节全部设置为val的值
unsigned char buf[128];
memset(buf,0x77,100);
memset(buf+100,0x77,10);
将前100个字节 填充为0x55
将第100-109字节填充为0x77
unsigned int abc[4];
memset(abc,0x55,sizeof(abc));
一个int类型数据对应4个字节,所以sizeof(abc)表示4×4个字节,所以abc[0]表示1个int数,对应着4个字节,已经被全部填充为55,abc[0]结果为0x55555555