所以,我只是坐下来决定写一个内存分配器。我累了,所以我只是扔了一些东西。我最终得到的是:
#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数组,其指针指向数组的第一个元素。
当我调用alloc值为4(这是int的大小,正如我在下面测试过的那样)时,它应该设置为指向数组的第四个元素。然后它应该返回一个char指针,指向转换为void指针的数组的前4个字节。
然后我将该值设置为大于char的最大值。 C应该意识到这是不可能的,然后应该将其截断为* num%sizeof(char)。
我猜测为什么会这样:当char指针被转换为void指针然后变成一个整数时,它会以某种方式改变指针的大小,使它能够指向一个整数。 (我不仅尝试了这个带整数的内存分配器,而且还使用了结构,它似乎也适用于它们。)
这个猜测是正确的,还是我太累了想不到?
编辑2:我想我已经明白了。我意识到我昨天的措词非常糟糕。抛弃我的事实是返回的指针实际指向一个char,但我仍然能以某种方式存储一个整数值。
答案 0 :(得分:1)
发布的allocator实现了标记和发布分配方案:
alloc(size)
个未分配的字节,则 size
返回有效指针。可用尺寸相应减小。请注意,此指针只能用于存储字节,因为它没有正确对齐其他任何内容。此外,根据对C标准的严格解释,即使指针正确对齐,使用它作为指向任何其他类型的指针也会违反严格的别名规则。
afree(ptr)
将竞技场重置为alloc()
返回ptr
之前的状态。使afree(NULL)
将竞技场重置为初始状态将是一个有用的扩展。
请注意,main()
函数尝试使用alloc(sizeof(int))
返回的指针作为指向int
的指针。这会调用未定义的行为,因为无法保证buffer
已正确对齐此行,并且因为违反了严格的别名规则。
另请注意,第二个参数的printf格式printf("%d: %d", *num, sizeof(int));
不正确。如果C运行时库太旧而无法支持printf("%d: %zd", *num, sizeof(int));
,则应为printf("%d: %d", *num, (int)sizeof(int));
或%zd
。
答案 1 :(得分:0)
其实!我想出了这个行为的原因!这就是我想知道的,然而,昨天我不太善于说出自己的话语(对不起)。我修改了我的代码:
#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 = 346455;
printf("%d: %d\n", *num, (int)sizeof(int));
printf("%d, %d, %d, %d", *(next - 4), *(next - 3), *(next - 2), *(next - 1));
afree(num);
}
现在,最后一个printf产生“87,73,5,0”。 如果将所有值转换为大二进制值,则得到:00000000 00000101 01001001 01010111.如果取二进制值并将其转换为十进制,则得到* num的原始值,即346455.因此,基本上它将整数为4个字节并将它们放入数组的不同元素中。我认为这是实现定义的,与little endian和big endian有关。它是否正确?我的第一个预测是它会截断整数并基本上将值设置为(整数值)%sizeof(char)。
答案 2 :(得分:-1)
int *num = alloc(sizeof(int));
说 - '这是一个指向某个空间的指针(alloc),让我们说它指向一个整数(int *)。'
你说
*num = 5643;
其中说 - 将该整数设置为5643。
为什么它不起作用 - 假设alloc实际上返回一个指向一个可以容纳整数的良好内存块的指针