首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“安全”内存管理

“安全”内存管理
EN

Code Review用户
提问于 2017-06-21 23:11:23
回答 1查看 187关注 0票数 6

为了简化对mallocrealloccalloc的调用失败的处理,我创建了几个文件来规定“安全”内存管理。这是我的项目stac的一部分,因此前缀将出现在下面的代码段中。此外,我决定使用snake_case而不是标准camelCase

我希望从中得到什么,以及我所面临的问题:这些功能是否存在于错误的实践中?是否有一种不同的方式来处理对内存分配器的失败调用?我写的代码有什么特别的错误吗?

safe_mem.c

代码语言:javascript
复制
#include "safe_mem.h"

void* safe_malloc(size_t size){
    void* memory = malloc(size);

    if(memory == NULL){
        free(memory);
        runtime_error("failed to allocate memory.");
    }

    return memory;
}

void* safe_calloc(size_t num, size_t size){
    void* memory = calloc(num, size);

    if(memory == NULL){
        free(memory);
        runtime_error("failed to allocate memory.");
    }

    return memory;
}

void* safe_realloc(void* ptr, size_t size){
    void* memory = realloc(ptr, size);

    if(memory == NULL){
        free(memory);
        runtime_error("failed to reallocate memory.");
    }

    return memory;
}

safe_mem.h

代码语言:javascript
复制
#ifndef STAC_SAFE_MEM
#define STAC_SAFE_MEM
#include <stdio.h>
#include <stdlib.h>
#include "error.h"

void* safe_malloc(size_t);
void* safe_calloc(size_t, size_t);
void* safe_realloc(void*, size_t);
#endif

error.c

代码语言:javascript
复制
#include "error.h"

void make_error(char* type, char* message){
    eprintf("%s error: %s\n", type, message);
}

void fatal_error(char* type, char* message, int exit_code){
    make_error(type, message);
    exit(exit_code);
}

void runtime_error(char* message){
    fatal_error("Runtime", message, STATUS_RUNTIME_ERROR);
}

void generic_error(char* message){
    fatal_error("Generic", message, STATUS_GENERIC_ERROR);
}

error.h

代码语言:javascript
复制
#ifndef STAC_ERROR
#define STAC_ERROR
#include <stdio.h>
#include <stdlib.h>

#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define STATUS_OKAY (0)
#define STATUS_RUNTIME_ERROR (1)
#define STATUS_GENERIC_ERROR (-1)

void make_error(char*, char*);
void fatal_error(char*, char*, int);

void runtime_error(char*);
void generic_error(char*);

#endif
EN

回答 1

Code Review用户

回答已采纳

发布于 2017-06-22 22:01:45

这些功能是否存在于不良实践中?

我要说的是,只要它们正在包装的原始函数具有相同的函数签名,就可以替换它们。

我写的代码有什么特别的错误吗?

分配0字节可能返回NULL,这并不表示内存不足.

calloc()realloc()也一样。

代码语言:javascript
复制
void* memory = malloc(size);
// if(memory == NULL){
if(memory == NULL && size > 0){

free(memory)之后调用if(memory == NULL)没有意义

代码语言:javascript
复制
if(memory == NULL){
  //  free(memory);

对于eprintf(...),考虑传递错误源的__FUNC____LINE__以帮助调试。或者至少创建唯一的错误消息。

代码语言:javascript
复制
void* safe_malloc(size_t size){
   runtime_error("failed to malloc memory.");

void* safe_calloc(size_t num, size_t size){
    runtime_error("failed to calloc memory.");

在几个地方,使用const可以更广泛地应用不改变引用数据的函数。

代码语言:javascript
复制
// void make_error(char* type, char* message){
void make_error(const char* type, const char* message){

我不喜欢你的名字-空间选择error.h,其中包括eprintf, STATUS_OKAY, STATUS_GENERIC_ERROR, make_error, ...,如果我说这些使用在其他..c文件,我将如何被引导回error.h/error.c作为他们的起源?虽然有点冗长,但我更喜欢error_printf, ERROR_STATUS_GENERIC,...

小调:#include <stdio.h>不必出现在safe_mem.h中,#include <stdlib.h>不需要出现在error.h中。error.c应该有#include <stdlib.h>,正如它所称的exit()error.c不应该依赖error.h,包括这一点。关于safe_mem.c的类似问题

从设计的角度来看,我还会包括void safe_free(void *),因为这些安全函数的功能可能会扩展,并且要求即使它现在什么也不做。它使safe_...()对称。

票数 6
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/166364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档