c - 了解堆中的内存分配
问题描述
我试图了解如何使用 malloc 在堆上分配内存,并遇到以下观察结果,但无法理解其背后的原因。如果有人可以解释,那就太好了。
首先,让我们看一下我写的代码:
#include<stdio.h>
#include<stdlib.h>
void print_int_heap(unsigned int *ptr, int len)
{
printf("PREV_SIZE: [%08x] SIZE: [%08x] MEM: [%08x] for INT malloc(%d)\n", *(ptr-2), *(ptr-1), ptr, len);
}
void print_char_heap(char *ptr, int len)
{
printf("PREV_SIZE: [%08x] SIZE: [%08x] MEM: [%08x] for CHAR malloc(%d)\n", *(ptr-2), *(ptr-1), ptr, len);
}
int main() {
unsigned int *ptr1 = malloc(20);
print_int_heap(ptr1, 20);
char *ptr2 = malloc(20)
print_char_heap(ptr2, 20);
return 0;
}
我为上述程序得到的输出是:
PREV_SIZE: [0x00000000] SIZE: [0x00000019] MEM: [0x0804b008] for INT malloc(20)
PREV_SIZE: [0x00000000] SIZE: [0x00000000] MEM: [0x0804b020] for INT malloc(20)
我可以理解 int malloc 的输出,但我不明白为什么 char malloc 的块大小的值为 0?
解决方案
Ifptr
是一个int*
,*(ptr - 1)
指的是什么引用sizeof(int)
之前的字节。ptr
这通常是一个 32 位的数量,从 . 之前的四个字节开始ptr
。
类似地,如果它是 a char*
,*(ptr - 1)
则指在什么引用sizeof(char)
之前的字节。始终为 1;通常这将是值之前的单个字节中的 8 位数量。ptr
sizeof(char)
ptr
这些显然是完全不同的东西。
顺便说一句,你可以写ptr[-1]
。但正如上面的分析所示,这真的不是你想要的。您想强制ptr
转换为指向您认为ptr
可能是之前的对象的数据类型的指针uint32_t
。
从技术上讲,这都是未定义的行为,但是如果您的malloc
实现是在分配之前存储数据并且您知道该数据的类型,我会说可以阅读它。(虽然盯着系统函数的内部数据看总是有点粗鲁。)
请注意,并非所有malloc
实现都做同样的事情。您很可能会在其他地方找到一个长度或根本没有的。
推荐阅读
- pandas - ValueError:无法将字符串转换为浮点数:'n/a'
- react-native - 通知已恢复但未显示飞艇 React Native
- javascript - 如何使用 JQuery 对表格列进行升序和降序排序?
- vue.js - VueJs - 在 v-select 之后包含一个按钮
- rally - Rally API - 仅获取用户故事的更新
- docker - 使用 docker 安装 swipl
- typescript - 在 Typescript 中使用 allowJs 选项使用 JS 时,如何将对象属性用作可选?
- laravel - Laravel找到具有差异条件的同一列之和的差异
- python - 如何在保持比例的同时使我的玩家图像在碰撞时更大?
- javascript - 我可以将国际象棋游戏/移动导入 React Chessboard 以仅以视觉格式显示移动吗?(实际上没玩)