堆内存(Heap Memory)是计算机程序中用于动态内存分配的内存区域。与栈内存(Stack Memory)不同,堆内存的分配和释放不是自动的,而是由程序员通过调用内存分配函数(如C语言中的 malloc
和 free
)来控制的。
const
关键字来定义常量。Linux C 程序当中一般使用 malloc()函数为程序分配一段堆内存,而使用 free()函数来释放这段内存,先来看下 malloc()函数原型,如下所示:
#include <stdlib.h>
void *malloc(size_t size);
size
字节的内存区域。NULL
。free
用于释放之前通过 malloc
、calloc
或 realloc
等函数分配的内存。这块内存空间在函数执行完成后不会释放,它们的值是未知的,所以通常需要程序员对 malloc()分配的堆内存进行内存释放操作。通常使用 free()函数释放堆内存, free()函数原型如下所示:
#include <stdlib.h>
void free(void *ptr);
下面是一个简单的C语言程序示例,演示了如何使用 malloc
和 free
进行动态内存分配和释放:
#include <stdio.h>
#include <stdlib.h> // 包含malloc和free函数的头文件
int main()
{
int n; // 定义一个整数变量,用于存储数组的大小
printf("Enter the size of the array you want to create: ");
scanf("%d", &n); // 从用户那里获取数组的大小
// 使用malloc动态分配一个整数数组的内存
int *array = (int *)malloc(n * sizeof(int));
if (array == NULL) {
// 如果分配失败,打印错误信息并退出程序
fprintf(stderr, "Error: Memory allocation failed!\n");
return 1;
}
// 初始化数组
for (int i = 0; i < n; i++) {
array[i] = i * i; // 例如,将数组元素设置为其索引的平方
}
// 打印数组内容
printf("Array elements:\n");
for (int i = 0; i < n; i++) {
printf("%d ", array[i]);
}
printf("\n");
// 使用完数组后,使用free释放分配的内存
free(array);
// 再次打印数组内容,此时应该输出未定义的值
printf("Attempt to print array after freeing memory:\n");
for (int i = 0; i < n; i++) {
printf("%d ", array[i]); // 此处访问已释放的内存,可能导致未定义行为
}
printf("\n");
return 0;
}
程序通过 malloc
函数动态分配一个整数数组的内存,大小由用户输入决定,用 free
函数释放之前分配的内存。尝试再次打印数组内容,这将导致未定义行为,因为内存已经被释放。运行结果如下:
alloc
与 malloc
类似,但有一些关键的区别。calloc
用于分配足够存储一个指定数量的对象的内存块,并且将分配的内存初始化为0。这种分配对于需要从零开始的数组或数据结构非常有用。calloc
函数原型:
#include <stdlib.h>
void *calloc(size_t num, size_t size);
num
:要分配的对象的数量。size
:每个对象的大小(以字节为单位)。calloc
返回指向分配内存的指针,并且这块内存的所有字节都被初始化为零。如果内存分配失败,calloc
返回 NULL
。下面是 calloc
函数的示例程序,程序会动态分配一个整数数组的内存,并初始化所有元素为零,然后打印数组的内容,最后释放内存。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n; // 数组的大小
printf("Enter the size of the array you want to create: ");
scanf("%d", &n); // 从用户那里获取数组的大小
// 使用calloc动态分配一个整数数组的内存,并初始化为零
int *array = (int *)calloc(n, sizeof(int));
if (array == NULL) {
// 如果分配失败,打印错误信息并退出程序
fprintf(stderr, "Error: Memory allocation failed!\n");
return 1;
}
// 打印数组内容,此时所有元素都是0
printf("Array elements (initialized to zero):\n");
for (int i = 0; i < n; i++) {
printf("%d ", array[i]);
}
printf("\n");
// 可以选择在这里修改数组的某些元素
// 例如:array[0] = 1; // 将第一个元素设置为1
// 使用完数组后,使用free释放分配的内存
free(array);
// 再次尝试访问数组内容,将会导致未定义行为
// printf("Attempt to print array after freeing memory: %d\n", array[0]);
return 0;
}
运行结果如下
C 函数库中还提供了一系列在堆上分配对齐内存的函数,对齐内存在某些应用场合非常有必要,常用于分配对其内存的库函数有: posix_memalign()、 aligned_alloc()、 memalign()、valloc()、 pvalloc(),如果不需要特定的对齐,通常使用 malloc()
和 calloc()
就足够了。它们的函数原型如下所示:
#include <stdlib.h>
int posix_memalign(void **ptr, size_t alignment, size_t size);
ptr
:指向一个 void*
的指针,函数将通过这个指针返回分配的内存的地址。alignment
:所需的内存对齐字节数,必须是2的幂,也必须是 sizeof(void*)
的倍数。size
:要分配的内存大小(以字节为单位)。#include <stdlib.h>
void *aligned_alloc(size_t alignment, size_t size);
alignment
:内存对齐的字节数,必须是2的幂。size
:要分配的内存大小。memalign()函数:与 posix_memalign
类似,分配一块至少 size
大小的内存,memalign()与 aligned_alloc()参数是一样的,它们之间的区别在于:对于参数 size 必须是参数 alignment
的整数倍这个条件, memalign()并没有这个条件。
#include <malloc.h>
void *memalign(size_t alignment, size_t size);
alignment
:所需的内存对齐字节数。size
:要分配的内存大小。#include <stdlib.h>
void *valloc(size_t size);
size
:要分配的内存大小。#include <malloc.h
void *pvalloc(size_t size);
size
:要分配的内存大小,必须是非负整数,并且足够大,以确保分配的内存至少有一个页面。#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <malloc.h>
int main()
{
void *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
size_t size = 1024; // 分配大小为1KB的内存
size_t alignment = ; // 指定内存对齐到字节边界
// 使用posix_memalign分配内存
if (posix_memalign(&ptr1, alignment, size) != 0) {
perror("posix_memalign failed");
return 1;
}
printf("Memory allocated by posix_memalign: %p\n", ptr1);
// 使用aligned_alloc分配内存
ptr2 = aligned_alloc(alignment, size);
if (ptr2 == NULL) {
perror("aligned_alloc failed");
return 1;
}
printf("Memory allocated by aligned_alloc: %p\n", ptr2);
// 使用memalign分配内存(GNU扩展)
ptr3 = memalign(alignment, size);
if (ptr3 == NULL) {
perror("memalign failed");
return 1;
}
printf("Memory allocated by memalign: %p\n", ptr3);
// 使用valloc分配内存
ptr4 = valloc(size);
if (ptr4 == NULL) {
perror("valloc failed");
return 1;
}
printf("Memory allocated by valloc: %p\n", ptr4);
// 使用pvalloc分配内存
ptr5 = pvalloc(size);
if (ptr5 == NULL) {
perror("pvalloc failed");
return 1;
}
printf("Memory allocated by pvalloc: %p\n", ptr5);
// 释放分配的内存
free(ptr1);
free(ptr2);
free(ptr3); // 注意:memalign分配的内存需要用free释放
free(ptr4);
free(ptr5); // 注意:pvalloc分配的内存需要用free释放
return 0;
}
运行结果如下:
0x5574280be040,
地址的最低几位数字(040)显示了内存对齐的情况,地址是按照16字节对齐的(因为040是16的倍数)。0x5574280beb80,
地址的最低几位数字(b80)表明内存也是按照16字节对齐的。0x5574280bf000,
地址以 000
结尾,表明内存是按照页面大小(通常是4096字节或4KB)对齐的。0x5574280c0000,
地址以 0000
结尾,进一步证实了 valloc
函数分配的内存确实是按照页面大小对齐的。0x5574280c1000
。同样以 000
结尾,表明这也是页面大小对齐的内存。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- igbc.cn 版权所有 湘ICP备2023023988号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务