我的非malloced指针指向什么?

时间:2018-01-12 11:46:09

标签: c pointers malloc

我已将邮箱简化为以下代码。 我有一个SetMsg(),GetMsg()和ClearMsg()函数。 在SetMsg()中,我的目的是存储消息,直到调用GetMsg(),此时存储的消息将返回给调用者,同样,我的目的是将先前存储的消息转换为NULL。

但是,由于我不是malloc任何事情,我想知道将信息存储在ptr_Msg中是否完全安全,就像我在下面做的那样?由于我无法控制在{I"已保存"之后存储msg的内存会发生什么。它ptr_Msgmsg的内存后来被som的其他变量分配,而我仍然指向那个地址?或者static声明ptr_Msg?拯救一天?

例如,msg在发送到signal时会带有成员SetMsg(),并将其存储在ptr_Msg中。然后,在此函数范围之外,msg更改其signal的值。如果我收到GetMsg(),我会返回signal的新值或达到SetMsg()时的值吗?

我应该做这样的事吗?在SetMsg()

Msg* tmp = (Msg*) msg;
ptr_Msg = (Msg*) malloc(sizeof *tmp);
memcpy(ptr_Msg, tmp, sizeof *tmp);

然后在ClearMsg()

free(ptr_Msg);
ptr_Msg = NULL;

当前代码:

typedef struct Msg {
    uint16_t signal;
} Msg_t;

static Msg_t* ptr_Msg = NULL;


bool GetMsg(char** msgData, uint16_t* sigNo) {
    *msgData = (char*) ptr_Msg;

    // Get message
    if (*msgData != NULL) {
        // do some stuff

        // and then
        ClearMsg();
        return true;
    }

    return false;
}

bool SetMsg(void* msg) {

    if (ptr_Msg!=NULL) {
        return false;
    }

    ptr_Msg = (Msg*) msg;

    return true;
}

void ClearMsg() {
    ptr_Msg = (Msg*) NULL;
}

编辑和可能的答案: 我设法得到了这个测试,当然,它没有水。 我已将代码更改为以下内容,似乎可以正常工作。我已使用"< ===新代码部分===>"标记了部件。

是否正确/安全地使用malloc和free?

typedef struct Msg {
    uint16_t signal;
} Msg_t;

static Msg_t* ptr_Msg = NULL;


bool GetMsg(char** msgData, uint16_t* sigNo) {
    *msgData = (char*) ptr_Msg;

    // Get message
    if (*msgData != NULL) {
        // do some stuff

        // and then
        ClearMsg();
        return true;
    }

    return false;
}

bool SetMsg(void* msg) {

    if (ptr_Msg!=NULL) {
        return false;
    }
    // <=== new code section ===>
    ptr_Msg = malloc(sizeof *ptr_Msg);        
    memcpy(ptr_Msg, (Msg_t*) msg, sizeof *ptr_Msg);
    // <===  ===>    
    return true;
}

void ClearMsg() {
    // <=== new code section ===>
    free(ptr_Msg);
    // <===  ===>
    ptr_Msg = (Msg*) NULL;
}

1 个答案:

答案 0 :(得分:0)

您的代码是围绕单个文件范围变量ptr_Msg的复杂包装器。这些函数定义了一个接口。此接口是与调用者签订的有关指针ptr_Msg引用的数据所有权的合同。只要合同未知,就不可能说你是否需要复制数据而不是存储指针。对于当前实现,调用者负责数据的生存时间至少持续指针引用数据的时间。如果您需要一个负责存储某些数据的容器(或邮箱),则需要使用类似的memcpy复制数据。

主要问题是,你想要什么? 合同是什么? 什么存储?