【发布时间】:2016-10-31 18:35:56
【问题描述】:
所以,我就坐下来决定写一个内存分配器。我累了,所以我只是扔了一些东西。我最终得到的是这样的:
#include <stdio.h>
#include <stdlib.h>
#define BUFSIZE 1024
char buffer[BUFSIZE];
char *next = buffer;
void *alloc(int n){
if(next + n <= buffer + BUFSIZE){
next += n;
return (void *)(next - n);
}else{
return NULL;
}
}
void afree(void *c){
next = (char *)c;
}
int main(){
int *num = alloc(sizeof(int));
*num = 5643;
printf("%d: %d", *num, sizeof(int));
afree(num);
}
由于某种原因,这行得通。但我无法解释它为什么起作用。这可能与我累的事实有关,但我真的不明白它为什么会起作用。所以,从逻辑上讲,这就是它应该做的事情,据我所知:
它创建一个 char 数组,其指针指向数组的第一个元素。
当我调用值为 4 的 alloc(这是一个 int 的大小,正如我在下面测试过的)时,它应该设置为指向数组的第四个元素。然后它应该返回一个 char 指针,指向转换为 void 指针的数组的前 4 个字节。
然后我将该值设置为大于 char 的最大值。 C 应该意识到这是不可能的,然后应该将其截断为 *num % sizeof(char)。
我有一个关于为什么会这样的猜测:当 char 指针被强制转换为 void 指针然后变成整数时,它会以某种方式改变指针的大小,以便它能够指向整数。 (我不仅尝试过使用整数的内存分配器,还尝试使用结构,而且它似乎也适用于它们)。
这个猜测是正确的,还是我太累了,无法思考?
编辑2:我想我已经理解了。我意识到我昨天的措辞很糟糕。让我失望的是返回的指针实际上指向一个字符,但我仍然能够以某种方式存储一个整数值。
【问题讨论】:
-
睡一觉,然后再看一遍。我猜你会明白的。
-
我认为您得到了指向的内容和错过的内容。
void *可以远大于字符的最大大小。这就是让你困惑的地方吗? -
“然后它应该返回一个 char 指针,指向转换为 void 指针的数组的前 4 个字节。”为什么?它返回一个
void *,它被转换为int *。 -
一般来说,它并不总是有效。分配两个浮点数,将它们设置为 1.0,然后释放分配的第一个浮点数。接下来,分配一个双精度并将其设置为 1.0,然后检查第二个浮点值。它改变了。
-
@hidefromkgb:很好的观察。事实上,对于任何不是以 LIFO 顺序成对匹配的
alloc()/afree()序列,它都完全被破坏了。仁慈的是,它是一个堆栈。
标签: c