使用宏来分配内存不好吗?

时间:2015-05-03 19:02:21

标签: c memory-management macros

我想使用这样的东西来分配内存:

void* pointers = NULL;
#define MALLOC(size) ({\
    void* ptr = malloc(size);
    ARRAYAPPEND(pointers, ptr);\
})
#define FREE(ptr) ({\
    ARRAYREMOVEBYVALUE(pointers, ptr);\
    free(ptr);\
})
#define FREEALL() ({\
    FREEARRAY(pointers);\
})

ARRAYAPPEND会将一个项目添加到数组中,或者当它指向NULL

时创建一个包含该项目的数组

ARRAYREMOVEBYVALUEfree()数组中具有匹配值的所有项目。如果数组中的所有值都匹配,它将使用FREEARRAY()释放整个数组。使用ARRAYREMOVEBYEXPRESSIONstrcmp(value, "")等内容也可以使用。 (不是我需要使用它)

ARRAYSIZE将返回数组的大小,或者当它指向NULL

时返回0

FREEARRAY将释放数组中的所有指针,然后释放数组本身。如果数组指向NULL,则不会采取任何操作。

当然,我也会支持realloccalloc

这是分配和释放内存的好方法吗,是否有一个更安全的方法(我从头开始创建这些宏),我应该free()每一个内存manualy,或者我应该依靠OS使用不安全但工作的自动清理? (目前,仅对Windows 8的支持完全正常,Windows 8具有自动清理功能)?我的目标是在程序退出时释放所有内存,显然不是运行时

(我可以自己发现

while (1) {
    malloc(10000);
}

肯定会耗尽内存,但我的问题是:

char* x = MALLOC(10000);
FREEALL();

比依赖操作系统清理更安全,如果这样:

char* x = malloc(10000);
free(x);

首选使用宏。也许隐藏的malloc来电我无法控制?在这些情况下,没有真正的理由使用宏,但例如

while (strcmp(SUBSTRING(str, 0, 14), "Hello, world!") {
    // Code (No cleanup)
})

在SUBSTRING中可能存在对malloc的隐藏调用(例如,用于创建新字符串),这些调用不会是free' d。在这种情况下我应该使用宏吗?

SESSION_SET("SESSION1");
while (strcmp(SUBSTRING(str, 0, 14), "Hello, world!") {
    // Code (No cleanup)
})
SESSION_FREE("SESSION1");

或依赖自动清理是否足够好?)

我的问题基本上是:我想在不保存地址的情况下分配内存,如果我强迫自己保存每个地址并且free()它是manualy,如果我使用宏,是否有任何库可以这对我来说,还是我应该依赖OS清理?

对@wildplasser评论的反应: 宏是一个内联函数......:| (编辑:好的......也许一个宏没有检查类型。但就是这样。)另外我更喜欢键入 键入<{p>>以上char* item = MALLOC(10);FREEALL();

void* array = NULL; // Array of pointers
char* item = malloc(10); // Allocate item
int size = (array == NULL ? 0 : sizeof(array) / sizeof(array[0])); // Get length of array
array = realloc(array, (size + 1) * sizeof(item)); // Reallocate array
array[size] = item; // Add item to new array
size = (array == NULL ? 0 : sizeof(array) / sizeof(array[0])); // Get new size of array (Wow, a macro would be usefull, wouldn't it?)
int i = 0; // Lets loop over all the items
while (i < size) { // In our array of pointers
    free(array[i]); // And free all those pointers
}
free(array); // Lets free the array too...
array = NULL; // What did we end up doing? Nothing!

1 个答案:

答案 0 :(得分:1)

你在这里的所有工作基本上都是无用的:它是错误的,并没有实现其目的。

程序分配的任何内存将在结束后返回给操作系统。这适用于所有使用虚拟内存的操作系统 - 想想任何32位或64位现代操作系统(现代操作系统意味着“本世纪制造”)。 如果操作系统没有这样做(或者没有操作系统),你就已经知道了。

因此,当程序仍在运行时,所有释放内存的问题都会适用。

分配内存的方式仅适用于您定义宏的这些转换单元。你将使用外部库的那一刻(最终你会),你将回到原点:

// this is a function that creates a texture (for drawing to screen). IT'S ENTIRELY OUT OF YOUR CONTROL.
SDL_Texture* SDL_CreateTexture(SDL_Renderer* renderer,
                               Uint32        format,
                               int           access, 
                               int           w,
                               int           h);

// somewhere in your code
SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STATIC, 128, 64);
// now what