C中的内存分配

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)


Ned*_*der 6

有一些问题:

  1. pointer在函数的中间声明,这在C中是不允许的.

  2. 你将指针设置为stack+size,但你希望它只是stack.否则,您将返回指向您正在分配的内存块末尾的指针.因此,如果调用者使用size该指针的所有字节,他将与另一块内存重叠.如果你在不同的时间获得不同大小的块,你将有两个调用者尝试使用相同的内存字节.

  3. 当你这样做时stack += size,你stack不是按size字节递增,而是按sizevoid*来递增,这几乎总是更大.

  • 自C99以来,允许在函数中间进行声明. (3认同)