The Linux Programming Interface 07 Memory Allocation 分配内存

本文详细介绍了Linux编程中用于堆和栈内存分配的函数,包括brk()、sbrk()、malloc()、free()、calloc()、realloc()以及alloca()。malloc()和free()用于动态分配和释放内存,calloc()用于初始化分配的内存,realloc()调整已分配内存的大小,alloca()则从栈中分配内存。理解这些函数对于避免内存管理错误至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The Linux Programming Interface

Memory Allocation

(1) 内容

This chapter describes the functions that are used to allocate memory on the heap or the stack.

To allocate memory, C programs normally use the malloc family of functions, which we describe shortly. However, we begin with a description of brk() and sbrk(), upon which the malloc functions are based.

#include <unistd.h>

int brk(void *end_data_segment);

The brk() system call sets the program break to the location specified by end_data_segment. Since virtual memory is allocated in units of pages, end_data_segment is effectively rounded up to the next page boundary.

On success, sbrk() returns the previous address of the program break.

The call sbrk(0) returns the current setting of the program break without changing it.

(02) malloc()函数,分配内存的使用

The malloc function allocates size bytes from the heap and returns a pointer to the start of the newly allocated block of memory.

#include <stdlib.h>

void *malloc(size_t size);

Because malloc() returns void *, we can assign it to any type of C pointer.

(03) free() 释放内存

void free(void *ptr);

The free function deallocates the block of memory pointed to by its ptr argument, which should be an address previously returned by malloc() or others.

(04) 展示free用例

#include "tlpi_hdr.h"
#define MAX_ALLOCS 1000000

int main(int argc, char *argv[]) {
	char *ptr[MAX_ALLOCS];
	int freeStep, freeMin, freeMax, blockSize, numAllocs, j;

	printf("\n");

	if (argc < 3 || strcmp(argv[1], "--help") == 0)
		usageErr("%s num-allocs block-size [step [min [max]]]\n", argv[0]);

	numAllocs = getInt(argv[1], GN_GT_0, "num-allocs");

	if (numAllocs > MAX_ALLOCS)
		cmdLineErr("num-allocs > %d\n", MAX_ALLOCS);

	blockSize = getInt(argv[2], GN_GT_0 | GN_ANY_BASE, "block-size");

	freeStep = (argc > 3) ? getInt(argv[3], GN_GT_0, "step") : 1;
	freeMin = (argc > 4) ? getInt(argv[4], GN_GT_0, "min") : 1;
	freeMax = (argc > 5) ? getInt(argv[5], GN_GT_0, "max") : numAllocs;

	if (freeMax > numAllocs)
		cmdLineErr("free-max > num-allocs\n");

	printf("Initial program break:		%10p\n", sbrk(0));

	printf("Allocating %d * %d bytes\n", numAllocs, blockSize);

	for (j = 0; j < numAllocs; j++) {
		ptr[j] = malloc(blockSize);
		if (ptr[j] == NULL)
			errExit("malloc");
	}

	printf("Program break is now:		%10p\n", sbrk(0));

	printf("Freeing blocks from %d to %d in steps of %d\n",
		freeMin, freeMax, freeStep);
		
	for (j = freeMin - 1; j < freeMax; j += freeStep)
		free(ptr[j]);

	printf("After free(), program break is: %10p\n", sbrk(0));

	exit(EXIT_SUCCESS);
}
输出:

wang@wang:~/test/tlpi-dist/lib$ ./free_and_sbrk 1000 10240 2

Initial program break:         0x19fa000
Allocating 1000 * 10240 bytes
Program break is now:         0x23c2000
Freeing blocks from 1 to 1000 in steps of 2
After free(), program break is:  0x23c2000
wang@wang:~/test/tlpi-dist/lib$ ./free_and_sbrk 1000 10240 1 1 999

Initial program break:          0xdb6000
Allocating 1000 * 10240 bytes
Program break is now:         0x177e000
Freeing blocks from 1 to 999 in steps of 1
After free(), program break is:  0x177e000

(05)malloc实现

The implementation of malloc() is straightforward. It first scans the list of memory blocks previously released by free() in order to find one whose size is larger than or equal to its requirement.

If it is larger, then it is split, so that a block of the correct size is returned to the caller and a smaller free block is left on the free list.

If no block on the free list is large enough, then malloc() calls sbrk() to allocate more memory.

(06)calloc使用

Here is an example of the use of calloc():
struct {/* Some field definitions */ } myStruct;
struct myStruct *p;

p = calloc(1000, sizeof(struct myStruct));
if (p == NULL)
    errExit("calloc");
(07)realloc函数使用

The realloc() function is used to resize (usually enlarge) a block of memory previously allocated by one of the functions in the malloc package.

void *realloc(void *ptr, size_t size);

(08) alloca()

Instead of obtaining memory from the heap, alloca() obtain memory from the stack by increasing the size of the stack frame.

void *alloca(size_t size);

(09) 总结

Using the malloc family of functions, a process can dynamically allocate and release memory on the heap. In considering the implementation of these functions, we saw that various things can go wrong in a program that mishandles the blocks of allocated memory, and we noted that a number of debugging tools are available to help locate the source of such errors.

    The alloca() function allocates memory on the stack. This memory is automatically deallocated when the function that calls alloca() returns.

(10)习题


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值