Linux-C编程-数据管理

1,内存管理

1.1 函数malloc

分配一块指定大小的内存。

原理:malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。
Linux Libc6采用的机制是在free的时候试图整合相邻的碎片,使其合并成为一个较大的free空间。

头文件:
#include <stdio.h>
函数原型:
void *malloc(size_t size);
参数说明:
size:待分配内存字节数量的参数,size_t为一个无符号整型。
返回值:
void*: malloc函数可以保证其返回的内存地址是对齐的,所以void *可以类型转换为任何类型的数据。返回NULL表示无法分配。

1.2 函数calloc

他为一个结构数据分配内存,并且需要元素个数以及元素的尺寸作为其参数。分配的内存会使用0进行填充。

头文件:
#include <stdio.h>
函数原型:
void *calloc(size_t number_of_elements, size_t element_size);
返回值:
void*: 返回一个指向第一个元素的指针。返回NULL表示无法分配。
与malloc函数类似,其后的调用并不会返回连续的空间, 所以我们不可能通过简单的再次调用calloc函数并且期望第二次调用所返回的内存添加到第一次调用的结束处,从而来扩大由calloc所分配的内存空间
示例程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(void)
{
    char *str = NULL;
    /* 分配内存空间 */
    str = (char*) calloc (10, sizeof(char));
    /* 将hello写入*/
    strcpy(str, "Hello");
    /*显示变量内容*/
    printf("String is %s\n", str);
    /* 释放空间 */
    free(str);
    return 0;
}

1.3 函数realloc

realloc会改变前一次分配的内存块的尺寸。

头文件:
#include <stdio.h>
函数原型:
void *realloc(void *existing_memory, size_t new_size);
返回值:
void*: 返回一个指向第一个元素的指针。返回NULL表示无法分配。
注意点1:realloc也许会需要能过移动数据来达到此目的,所以很重要的一点就是要保证一旦内存被重新分配了,我们必须使用新的指针,而不要试图使用realloc调用以前的指针来访问内存。
注意点2:如果realloc不可以调整内存,他就会返回一个NULL。这就意味着,在某些程序中,我们 应避免编写类似如下的代码
my_ptr = malloc(BLOCK_SIZE);
....
my_ptr = realloc(my_ptr, BLOCK_SIZE * 10);
因为如果realloc函数调用失败,他就会返回一个空指针;my_ptr就会指向空;那么原始的由malloc所分配的内存就不可以使用my_ptr来访问了。很可能我们所需要做的是首先访问由malloc所分配的新内存,然后使用memcpy函数将旧内存块的数据拷贝到新内存块。一旦出现错误,这可以使得程序重新访问存储在原始内存块中的数据,也许就是在执行程序清理的时候。

1.4 函数free

头文件:
#include <stdlib.h>
函数原型:
void free(void *ptr)
参数说明:
ptr:调用free时使用的参数指针必须是指向由malloc、calloc或realloc调用所分配的内存
使用示例:

#include  <stdio.h>
#define ONE_K (1024)
int main()
{
    char *some_memory;
    int exit_code = EXIT_FAILURE;
    some_memory = (char *)malloc(ONE_K);
    if (some_memory != NULL) {
        free(some_memory);
        exit_code = EXIT_SUCCESS;
    }
    exit(exit_code);
}

Q:C语言中,free()函数怎么知道释放多大的空间?

在C语言中,可以传递任意类型的指针作为free()函数的参数,但是free()函数怎么知道需要释放多少已分配的内存空间呢?当传递一个指针给某些函数的同时,不得不传递相应的所占空间的大小(例如,10个char类型的元素组成的数组,作为函数参数的同时,需要将其长度10作为函数参数传递),但是,并没有传递给free()指针所指向空间的大小啊。

A:通常,当malloe()等内存分配函数分配一块内存时,它们所获取的内存总是比所要求的稍大一些。它们返回的并不是这块内存的起始地址,而是一个比起始地址稍往后一点的一个地址。一些有关信息,例如所分配的内存块的大小,将被存放在这两个地址之间的那部分区域中
(如果这部分内容被改写,当所分配的这块内存被释放后你的程序中就会出现野指针)。这样,只要检查这部分信息,free()()函数就能知道要释放的内存块的大小了。

2,文件锁定

linux下文件锁定有两种:一种是以原子操作方式创建锁文件;另一种是允许锁定文件的一部分,从而独享对这一部分内容的访问。

2.1 创建锁文件

许多应用程序只需要能够针对某个资源创建一个锁文件(其实就是一个普通文件),然后其他程序通过检查这个文件(是否存在的状态)来判断它们是否被允许访问某个资源。简而言之,就是使用“系统不允许创建同名文件”这个限制来假借普通文件实现锁机制。创建锁文件使用fcntl.h头文件定义的open系统调用,并带上O_CREAT和O_EXCL标志。这样就以原子操作完成两项工作:确定文件不存在,然后创建之。 

示例代码:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>

const char *lock_file = "/tmp/LCK.test";
int main()
{
	int file_desc;
	int tries = 10;
	while (tries--)
	{
		file_desc = open(lock_file, O_RDWR | O_CREAT | O_EXCL, 0444);
		if (file_desc == -1) 	//creating file failed
		{
			printf("%d - Lock already present\n", getpid());
			sleep(2);
		}
		else //进入临界区
		{
			printf("%d - I have exclusive access\n", getpid());
			sleep(1);
			(void)close(file_desc);
			(void)unlink(lock_file);//leave critical section
			sleep(2);
		}
	}
	exit(EXIT_SUCCESS);
}

















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值