“carey_ou”通过精心收集,向本站投稿了7篇C 语言free 函数的原理,以下是小编整理后的C 语言free 函数的原理,欢迎阅读分享,希望对您有所帮助。

C 语言free 函数的原理

篇1:C 语言free 函数的原理

今天在网上看到了这样一个问题,“如果malloc 了一块字符串的内存,然后,它改变了这个字符串的大小,问会不会有一部分内存没有被释放掉,”这个问题,以前的确没有仔细想过。

当然,我觉得是肯定会释放掉的,但是一直没有了解过free 的原理,不敢乱说。我看了一下操作系统的内存管理,基本上是这样的,当然各个系统的实现不一样。

操作系统管理内存,维护了一个空闲内存链表,malloc从个链表中选出一个来使用,每个内存块都有一个头部来表示这个内存的基本信息,如内存大小,

所以free 时候 能够记住原来指针所指的内存大小,而不是用内存块中是否有 \0 来临时计算指向内存的大小,不要字符串的计算长度的方法所误导,

还有一点要注意的就是,系统在free 内存的时候,记住的只是 malloc 时候的地址,和 分配内存的大小。

比如 char *p = (char *)malloc(10); 就会产生分配10个 字节。如果 你把指针的地址改变了 p = p + 1; 然后 free 就要出问题了。程序会崩溃。

如果一定要改变指针的值,建议这样做 char *newp = p; 然后 改变 newp = newp + 1 , 最后 free(p);

还有一点要注意,一个长度 为10 的字符串 要占用 11个字节。因为还有一个 '\0', 所以分配内存的时候要分配 lenght + 1 的大小。

篇2:c语言函数天天见

总结在学习过程中遇到的c语言函数:

1、相关函数:fstat, lstat, chmod, chown, readlink, utime

头文件:#include#include

定义函数:int stat(const char * file_name, struct stat *buf);

函数说明:stat用来将参数file_name 所指的文件状态, 复制到参数buf 所指的结构中,成功返回0,失败返回-1. stat结构体内详细信息不再赘述,可以参考其他博客资料。

使用方法:

struct stat sa;

if(stat(filename,&sa)<0)

{

return -1;

}

....

2、memset

总的作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c。

#include

using namespace std;

void main()

{

char s[20];

cout<<“s大小”<

3、rand(),RAND_MAX

rand()产生随机数的一个随机函数;

RAND_MAX是C中stdlib.h中宏定义的一个字符常量:

#define RAND_MAX Ox7FFF

其值最小为32767,最大为2147483647

通常在产生随机小数时可以使用RAND_MAX,

#include

#include

#include

using namespace std;

int main(void)

{

srand((unsigned int)time(NULL));

double a[10];

int i;

cout<

篇3:c语言函数知识点总结

第一节、对C语言的基础认识

1、C语言编写的程序称为源程序,又称为编译单位。

2、C语言书写格式是自由的,每行可以写多个语句,可以写多行。

3、一个C语言程序有且只有一个main函数,是程序运行的起点。

第二节、熟悉vc++

1、VC是软件,用来运行写的C语言程序。

2、每个C语言程序写完后,都是先编译,后链接,最后运行。(.c—.obj—.exe)这个过程中注意.c和.obj文件时无法运行的,只有.exe文件才可以运行。(常考!)

第三节、标识符

1、标识符(必考内容):

合法的要求是由字母,数字,下划线组成。有其它元素就错了。

并且第一个必须为字母或则是下划线。第一个为数字就错了

2、标识符分为关键字、预定义标识符、用户标识符。

关键字:不可以作为用户标识符号。main define scanf printf 都不是关键字。迷惑你的地方If是可以做为用户标识符。因为If中的第一个字母大写了,所以不是关键字。

预定义标识符:背诵define scanf printf include。记住预定义标识符可以做为用户标识符。

用户标识符:基本上每年都考,详细请见书上习题。

第四节:进制的转换

十进制转换成二进制、八进制、十六进制。

二进制、八进制、十六进制转换成十进制。

第五节:整数与实数

1)C语言只有八、十、十六进制,没有二进制。但是运行时候,所有的进制都要转换成二进制来进行处理。(考过两次)

a、C语言中的八进制规定要以0开头。018的数值是非法的,八进制是没有8的,逢8进1。

b、C语言中的十六进制规定要以0x开头。

2)小数的合法写法:C语言小数点两边有一个是零的话,可以不用写。

1.0在C语言中可写成1.

0.1在C语言中可以写成.1。

3)实型数据的合法形式:

a、2.333e-1 就是合法的,且数据是2.333×10-1。

b、考试口诀:e前e后必有数,e后必为整数。请结合书上的例子。

4) 整型一般是4个字节, 字符型是1个字节,双精度一般是8个字节:

long int x; 表示x是长整型。

unsigned int x; 表示x是无符号整型。

第六、七节:算术表达式和赋值表达式

核心:表达式一定有数值!

1、算术表达式:+,-,*,/,%

考试一定要注意:“/” 两边都是整型的话,结果就是一个整型。 3/2的结果就是1.

“/” 如果有一边是小数,那么结果就是小数。 3/2.0的结果就是0.5

“%”符号请一定要注意是余数,考试最容易算成了除号。)%符号两边要求是整数。不是整数就错了。[注意!!!]

2、赋值表达式:表达式数值是最左边的数值,a=b=5;该表达式为5,常量不可以赋值。

1、int x=y=10: 错啦,定义时,不可以连续赋值。

2、int x,y;

x=y=10; 对滴,定义完成后,可以连续赋值。

3、赋值的左边只能是一个变量。

4、int x=7.7;对滴,x就是7

5、float y=7;对滴,x就是7.0

3、复合的`赋值表达式:

int a=2;

a*=2+3;运行完成后,a的值是12。

一定要注意,首先要在2+3的上面打上括号。变成(2+3)再运算。

4、自加表达式:

自加、自减表达式:假设a=5,++a(是为6), a++(为5);

运行的机理:++a 是先把变量的数值加上1,然后把得到的数值放到变量a中,然后再用这个++a表达式的数值为6,而a++是先用该表达式的数值为5,然后再把a的数值加上1为6,

再放到变量a中。 进行了++a和a++后 在下面的程序中再用到a的话都是变量a中的6了。

考试口诀:++在前先加后用,++在后先用后加。

5、逗号表达式:

优先级别最低。表达式的数值逗号最右边的那个表达式的数值。

(2,3,4)的表达式的数值就是4。

z=(2,3,4)(整个是赋值表达式) 这个时候z的值为4。(有点难度哦!)

z= 2,3,4 (整个是逗号表达式)这个时候z的值为2。

补充:

1、空语句不可以随意执行,会导致逻辑错误。

2、注释是最近几年考试的重点,注释不是C语言,不占运行时间,没有分号。不可以嵌套!

3、强制类型转换:

一定是 (int)a 不是 int(a),注意类型上一定有括号的。

注意(int)(a+b) 和(int)a+b 的区别。 前是把a+b转型,后是把a转型再加b。

4、三种取整丢小数的情况:

1、int a =1.6;

2、(int)a;

3、1/2; 3/2;

第八节、字符

C 语言free 函数的原理1)字符数据的合法形式::

‘1’ 是字符占一个字节,”1”是字符串占两个字节(含有一个结束符号)。

‘0’ 的ASCII数值表示为48,’a’ 的ASCII数值是97,’A’的ASCII数值是65。

一般考试表示单个字符错误的形式:’65’ “1”

字符是可以进行算术运算的,记住: ‘0’-0=48

大写字母和小写字母转换的方法: ‘A’+32=’a’ 相互之间一般是相差32。

2)转义字符:

转义字符分为一般转义字符、八进制转义字符、十六进制转义字符。

一般转义字符:背诵\0、、’、”、。

八进制转义字符: ‘141’ 是合法的, 前导的0是不能写的。

十六进制转义字符:’x6d’ 才是合法的,前导的0不能写,并且x是小写。

3、字符型和整数是近亲:两个具有很大的相似之处

char a = 65 ;

printf(“%c”, a); 得到的输出结果:a

printf(“%d”, a); 得到的输出结果:65

第九节、位运算

1)位运算的考查:会有一到二题考试题目。

总的处理方法:几乎所有的位运算的题目都要按这个流程来处理(先把十进制变成二进制再变成十进制)。

例1: char a = 6, b;

b = a<<2; 这种题目的计算是先要把a的十进制6化成二进制,再做位运算。

例2: 一定要记住,异或的位运算符号” ^ ”。0 异或 1得到1。

0 异或 0得到0。两个女的生不出来。

考试记忆方法:一男(1)一女(0)才可以生个小孩(1)。

例3: 在没有舍去数据的时候,<<左移一位表示乘以2;>>右移一位表示除以2。

篇4:c语言函数知识点总结

第一节:数据输出(一)(二)

1、使用printf和scanf函数时,要在最前面加上#include“stdio.h”

2、printf可以只有一个参数,也可以有两个参数。(选择题考过一次)

3、printf(“ 第一部分 ”,第二部分 );把第二部分的变量、表达式、常量以第一部分的形式展现出来!

4、printf(“a=%d,b=%d”,12, 34) 考试重点!

一定要记住是将12和34以第一部分的形式现在在终端也就是黑色的屏幕上。考试核心为:一模一样。在黑色屏幕上面显示为 a=12,b=34

printf(“a=%d, b=%d”,12, 34)那么输出的结果就是:a=12,

b=34

5、int x=017; 一定要弄清楚为什么是这个结果!过程很重要

printf(“%d”, x); 15

printf(“%o”, x); 17

printf(“%#o”,x); 017

printf(“%x”, x); 11

printf(“%#x”,x); 0x11

6、int x=12,y=34; 注意这种题型

char z=‘a’;

printf(“%d ”,x,y); 一个格式说明,两个输出变量,后面的y不输出

printf(“%c”,z); 结果为:12a

7、一定要背诵的

格式说明 表示内容 格式说明 表示内容

%d 整型 int %c 字符 char

%ld 长整型 long int %s 字符串

%f 浮点型 float %o 八进制

%lf double %#o 带前导的八进制

%% 输出一个百分号 %x 十六进制

%5d %#x 带前导的十六进制

举例说明:

printf(“%2d”,123 ); 第二部分有三位,大于指定的两位,原样输出123

printf(“%5d”,123 ); 第二部分有三位,小于指定的五位,左边补两个空格 123

printf(“%10f”,1.25 ); 小数要求补足6位的,没有六位的补0,。结果为 1.250000

printf(“%5.3f”,125 ); 小数三位,整个五位,结果为1.250(小数点算一位)

printf(“%3.1f”,1.25 );小数一位,整个三位,结果为1.3(要进行四舍五入)

第二节 数据输入

1、scanf(“a=%d,b=%d”,&a,&b) 考试超级重点!

一定要记住是以第一部分的格式在终端输入数据。考试核心为:一模一样。

在黑色屏幕上面输入的为 a=12,b=34才可以把12和34正确给a和b 。有一点不同也不行。

2、scanf(“%d,%d”,x,y);这种写法绝对错误,scanf的第二个部分一定要是地址!

scanf(“%d,%d”,&x,&y);注意写成这样才可以!

3、特别注意指针在scanf的考察

例如: int x=2;int *p=&x;

scanf(“%d”,x); 错误 scanf(“%d”,p);正确

scanf(“%d”,&p); 错误 scanf(“%d”,*p)错误

4、指定输入的长度 (考试重点)

终端输入:1234567

scanf(“%2d%4d%d”,&x,&y,&z);x为12,y为3456,z为7

终端输入:1 234567 由于1和2中间有空格,所以只有1位给x

scanf(“%2d%4d%d”,&x,&y,&z);x为1,y为2345,z为67

5、字符和整型是近亲:

int x=97;

printf(“%d”,x); 结果为97

printf(“%c”,x); 结果为 a

6、输入时候字符和整数的区别(考试超级重点)

scanf(“%d”,&x);这个时候输入1,特别注意表示的是整数1

scanf(“%c”,&x);这个时候输入1,特别注意表示的是字符‘1’ASCII为整数48。

补充说明:

1)scanf函数的格式考察:

注意该函数的第二个部分是&a 这样的地址,不是a;

scanf(“%d%d%*d%d”,&a,&b,&c); 跳过输入的第三个数据。

2)putchar ,getchar 函数的考查:

char a = get) 是没有参数的,从键盘得到你输入的一个字符给变量a。

put‘y’)把字符y输出到屏幕中。

3)如何实现两个变量x ,y中数值的互换(要求背下来)

不可以把 x=y ,y=x; 要用中间变量 t=x;x=y;y=t。

4)如何实现保留三位小数,第四位四舍五入的程序,(要求背下来)

y=(int)(x*100+0.5)/100.0 这个保留两位,对第三位四舍五入

y=(int)(x*1000+0.5)/1000.0 这个保留三位,对第四位四舍五入

y=(int)(x*10000+0.5)/10000.0 这个保留四位,对第五位四舍五入

这个有推广的意义,注意 x = (int)x 这样是把小数部分去掉。

篇5:c语言函数知识点总结

特别要注意:C语言中是用非0表示逻辑真的,用0表示逻辑假的。

C语言有构造类型,没有逻辑类型。

关系运算符号:注意<=的写法,==和=的区别!(考试重点)

if只管后面一个语句,要管多个,请用大括号!

1)关系表达式:

a、表达式的数值只能为1(表示为真),或0(表示假)。

如 9>8这个关系表达式是真的,所以9>8这个表达式的数值就是1。

如 7<6这个关系表达式是假的,所以7<6这个表达式的数值就是0

b、考试最容易错的:就是int x=1,y=0,z=2;

x

篇6:C语言sprintf与sscanf函数

1、前言

我们经常涉及到数字与字符串之间的转换,例如将32位无符号整数的ip地址转换为点分十进制的ip地址字符串,或者反过来,从给定的字符串中提取相关内容,例如给定一个地址:www.bokeyuan.cn:2345,我们要从地址中提出协议,主机地址和端口号。之前对字符串和数字之间的关系不是很熟悉,工作中经常涉及到这个,如是好好总结一下。C语言提供了一些列的格式化输入输出函数,最基本的是面向控制台标准输出和输入的printf和scanf,其实还有面向字符串的sprint和sscanf,面向文件的流的fprintf和fscanf。今天着重总结一下sprintf和sscanf系列函数,这两个函数类似于scanf和printf ,不同点是从字符串*buffer用于输入输出。

2、sprintf函数

sprintf函数原型为 int sprintf(char *str, const char *format, ...)。作用是格式化字符串,具体功能如下所示:

(1)将数字变量转换为字符串。

(2)得到整型变量的16进制和8进制字符串。

(3)连接多个字符串。

举例如下所示:

1 char str[256] = { 0 };

2 int data = 1024;

3 //将data转换为字符串

4 sprintf(str,“%d”,data);

5 //获取data的十六进制

6 sprintf(str,“0x%X”,data);

7 //获取data的八进制

8 sprintf(str,“0%o”,data);

9 const char *s1 = “Hello”;

10 const char *s2 = “World”;

11 //连接字符串s1和s2

12 sprintf(str,“%s %s”,s1,s2);

3、sscanf函数

sscanf函数原型为int sscanf(const char *str, const char *format, ...)。将参数str的字符串根据参数format字符串来转换并格式化数据,转换后的结果存于对应的参数内。具体功能如下:

(1)根据格式从字符串中提取数据。如从字符串中取出整数、浮点数和字符串等。

(2)取指定长度的字符串

(3)取到指定字符为止的字符串

(4)取仅包含指定字符集的字符串

(5)取到指定字符集为止的字符串

sscanf可以支持格式字符%[]:

(1)-: 表示范围,如:%[1-9]表示只读取1-9这几个数字 %[a-z]表示只读取a-z小写字母,类似地 %[A-Z]只读取大写字母

(2)^: 表示不取,如:%[^1]表示读取除'1'以外的所有字符 %[^/]表示除/以外的所有字符

(3),: 范围可以用“,”相连接 如%[1-9,a-z]表示同时取1-9数字和a-z小写字母

(4)原则:从第一个在指定范围内的数字开始读取,到第一个不在范围内的数字结束%s 可以看成%[] 的一个特例 %[^ ](注意^后面有一个空格!)

解析网址的例子如下所示:

1 const char *s = “www.baidu.com:1234”;

2 char protocol[32] = { 0 };

3 char host[128] = { 0 };

4 char port[8] = { 0 };

5 sscanf(s,“%[^:]://%[^:]:%[1-9]”,protocol,host,port);

6

7 printf(“protocol: %s\n”,protocol);

8 printf(“host: %s\n”,host);

9 printf(“port: %s\n”,port);

10

4、snprintf函数

snprintf函数是sprintf函数的更加安全版本,考虑到字符串的字节数,防止了字符串溢出。函数形式为:int snprintf(char *restrict buf, size_t n, const char * restrict format, ...);。最多从源串中拷贝n-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为n 的话,将不会溢出。

5、测试程序

本次采用ip地址和整型之间的转换,mac地址转换作为测试程序,整个程序如下所示:

1 #include

2 #include

3

4 #define IP_STR_LEN 18

5 #define MAC_STR_LEN 18

6 #define MAC_BIT_LEN 6

7 #define LITTLE_ENDIAN 0

8 #define BIG_ENDIAN 1

9

10 typedef unsigned char uchar;

11 typedef unsigned int uint;

12

13 int big_little_endian

14 {

15 int data = 0x1;

16 if (*((char*)&data) == 0x1)

17 return LITTLE_ENDIAN;

18 return BIG_ENDIAN;

19 }

20

21 uint ipstr2int(const char * ipstr)

22 {

23 assert(ipstr);

24 uint a,b,c,d;

25 uint ip = 0;

26 sscanf(ipstr,“%u.%u.%u.%u”,&a,&b,&c,&d);

27 a = (a << 24) ;

28 b = (b << 16) ;

29 c = (c << 8) ;

30 d = (d << 0) ;

31 ip = a | b | c | d;

32 return ip;

33 }

34

35 char *int2ipstr(const uint ip, char *ipstr, const uint ip_str_len)

36 {

37 assert(ipstr);

38 if (big_little_endian() == LITTLE_ENDIAN)

39 sprintf(ipstr,“%u.%u.%u.%u”,

40 (uchar)*((char*)(&ip)+3),

41 (uchar)*((char*)(&ip)+2),

42 (uchar)*((char*)(&ip)+1),

43 (uchar)*((char*)(&ip)+0));

44 else

45 sprintf(ipstr,“%u.%u.%u.%u”,

46 (uchar)*((char*)(&ip)+0),

47 (uchar)*((char*)(&ip)+1),

48 (uchar)*((char*)(&ip)+2),

49 (uchar)*((char*)(&ip)+3));

50

51 return ipstr;

52 }

53

55 char *mac2str(const unsigned char *mac,char *mac_str,const uint mac_str_len)

56 {

57 assert(mac_str);

58 sprintf(mac_str,“%02X-%02X-%02X-%02X-%02X-%02X”,

59 mac[0],mac[1],mac[2],

60 mac[3],mac[4],mac[5]);

61 }

62

63 int main()

64 {

65 char ip_str[IP_STR_LEN] = {0};

66 char mac_str[MAC_STR_LEN] = {0};

67 unsigned char mac[MAC_BIT_LEN] = {0XEF,0XAD,0XF4,0X4F,0XAA,0X0F};

68 const char *ipstr = “10.0.3.193”;

69 unsigned int ip;

70 int2ipstr(167773121,ip_str,IP_STR_LEN);

篇7:C语言内存分配函数malloc、calloc和realloc

C语言中常用的内存分配函数有malloc、calloc和realloc等三个,其中,最常用的肯定是malloc,这里简单说一下这三者的区别和联系,

1、声明

这三个函数都在stdlib.h库文件中,声明如下:

void* realloc(void* ptr, unsigned newsize);

void* malloc(unsigned size);

void* calloc(size_t numElements, size_t sizeOfElement);

它们的功能大致类似,就是向操作系统请求内存分配,如果分配成功就返回分配到的内存空间的地址,如果没有分配成功就返回NULL。

2、功能

malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。

calloc(n,size):在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址。

realloc(*ptr,size):将ptr内存大小增大或缩小到size。

需要注意的是realloc将ptr内存增大或缩小到size,这时新的空间不一定是在原来ptr的空间基础上,增加或减小长度来得到,而有可能(特别是在用realloc来增大ptr的内存空间的时候)会是在一个新的内存区域分配一个大空间,然后将原来ptr空间的内容拷贝到新内存空间的起始部分,然后将原来的空间释放掉。因此,一般要将realloc的返回值用一个指针来接收,下面是一个说明realloc函数的例子。

#include#includeint main(){ //allocate space for 4 integers int *ptr=(int *)malloc(4*sizeof(int)); if (!ptr) { printf(“Allocation Falure!\n”); exit(0); } //print the allocated address printf(“The address get by malloc is : %p\n”,ptr); //store 10、9、8、7 in the allocated space int i; for (i=0;i<4;i++) { ptr[i]=10-i; } //enlarge the space for 100 integers int *new_ptr=(int*)realloc(ptr,100*sizeof(int)); if (!new_ptr) { printf(“Second Allocation For Large Space Falure!\n”); exit(0); } //print the allocated address printf(“The address get by realloc is : %p\n”,new_ptr); //print the 4 integers at the beginning printf(“4 integers at the beginning is:\n”); for (i=0;i<4;i++) { printf(“%d\n”,new_ptr[i]); } return 0;}运行结果如下:

从上面可以看出,在这个例子中新的空间并不是以原来的空间为基址分配的,而是重新分配了一个大的空间,然后将原来空间的内容拷贝到了新空间的开始部分,

3、三者的联系

calloc(n,size)就相当于malloc(n*size),而realloc(*ptr,size)中,如果ptr为NULL,那么realloc(*ptr,size)就相当于malloc(size)。

阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。