Rad*_*dek 5 c malloc memory-management sbrk
以下是一个非常非常简单的malloc()版本,并且似乎为我分配了一些空间,但除了没有free()之外我不检查我是否已超出分配的空间,怎么能我检查代码是否正确?
"C"专家会打击我的任何明显错误?
#include <stdio.h>
#include <unistd.h>
#define MAX_MEMORY 1024 * 1024 * 2 /* 2MB of memory */
void *stack = NULL; /* pointer to available stack */
void * memoryAlloc(size) {
if (stack == NULL)
stack = sbrk(MAX_MEMORY); /* give us system memory */
void *pointer;
pointer = (void *)stack + size; /* we always have space :) */
stack += size; /* move in stack forward as space allocated */
return pointer;
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*urr 11
除了Ned Batchelder指出的基本问题之外,一个更微妙的问题是分配器必须返回一个正确对齐的地址,以便分配任何对象.在某些平台(x86)上,除性能问题外,这可能无关紧要,但在许多平台上,这是一个完全的交易破坏者.
我还必须执行一个(char*)强制转换来执行stack指针运算(你不能对void*类型进行指针运算).
你应该把parens放在MAX_MEMORY宏中的表达式周围.我不认为没有它们会有任何优先级问题,因为除了乘法之外的所有高优先级运算符都不是正确的语法.使用宏,它总是比抱歉更安全.(至少有一个例外,即[]操作符只能绑定到2整个MAX_MEMORY表达式,而不是整个表达式,但MAX_MEMORY[arrayname]即使它在语法上有效,也会看到一个非常奇怪的情况).
事实上,我会把它作为一个枚举.
您可以通过返回一个内存块来保持分配器简单,该内存块已正确对齐系统上的任何基本数据类型(可能是8字节对齐):
/* Note: the following is untested */
/* it includes changes suggested by Batchelder */
#include <stdio.h>
#include <unistd.h>
enum {
kMaxMemory = 1024 * 1024 * 2, /* 2MB of memory */
kAlignment = 8
};
void *stack = NULL; /* pointer to available stack */
void * memoryAlloc( size_t size) {
void *pointer;
size = (size + kAlignment - 1) & ~(kAlignment - 1); /* round size up so allocations stay aligned */
if (stack == NULL)
stack = sbrk(kMaxMemory); /* give us system memory */
pointer = stack; /* we always have space :) */
stack = (char*) stack + size; /* move in stack forward as space allocated */
return pointer;
}
Run Code Online (Sandbox Code Playgroud)
有一些问题:
你pointer在函数的中间声明,这在C中是不允许的.
你将指针设置为stack+size,但你希望它只是stack.否则,您将返回指向您正在分配的内存块末尾的指针.因此,如果调用者使用size该指针的所有字节,他将与另一块内存重叠.如果你在不同的时间获得不同大小的块,你将有两个调用者尝试使用相同的内存字节.
当你这样做时stack += size,你stack不是按size字节递增,而是按sizevoid*来递增,这几乎总是更大.
| 归档时间: |
|
| 查看次数: |
1018 次 |
| 最近记录: |