最后一个字节的内存损坏



我有一个函数,它返回一个指向结构体的指针,如下所示:

//header file
typedef struct {
        unsigned char *buffer;
        uint8_t       len;
} T_ABC_PACKET
在主文件中,我创建了一个指向函数的指针,并尝试打印这个
T_ABC_PACKET *pct = NULL;
pct = function_that_return_the_packet;
printf("value of packet is %s n", pct->buffer);

的结果在打印函数中总是一致的。我期望缓冲区有8个字节,最后一个字节总是一个损坏的内存。value = 10000357 ' 2U

但是如果我在函数内打印缓冲区:

T_ABC_PACKET* function_that_return_the_packet {
T_ABC_PACKET *pct = NULL;
char string_temp[80];
//some more initialization...
pct->buffer = (unsigned char *)string_temp;
pct->len = 5;
printf("value of packet is %s n", pct->buffer);
return pct;
}

函数中打印的值为10000357f。只有最后一个字符被损坏。这总是提供一个一致的值,没有很多次我运行程序,只有最后一个字符在函数的调用者中被损坏。我知道一个可能的情况是内存泄漏,但我试着仔细检查,我不能找到任何泄漏。我如何得到pct->缓冲区有正确的一切?

看起来您正在返回一个指向未定义行为的局部变量的指针,string_tempfunction_that_return_the_packet的局部变量,并且在退出该函数后将不存在

Daniel建议使用strdup可能是解决问题的最简单方法:

pct->buffer = strdup(string_temp);

确保你检查它没有失败。当然也可以先用malloc,再用strcpy

一旦你修复了返回指针到local的未定义行为(参见Shafik Yaghmour回答),你仍然有未定义的行为:看起来缓冲区不是null终止的,所以%s格式说明符读取它,只有当它发现一个不相关的时才停止。

如果你知道缓冲区的长度不能超过8,你可以把它的内容复制到一个字符缓冲区,最多pct->len,然后在末尾插入一个结束符:

char tmpBuf[9]; // max length is 8, plus one for null ternminator
memcpy(tmpBuf, pct->buffer, pct->len);
tmpBuf[pct->len] = '';
printf("value of packet is %s n", tmpBuf);

这就是问题的根源:

pct->buffer = (unsigned char *)string_temp;

'string_temp'在堆栈上分配。当函数返回时,它稍后会在某个地方被销毁,或者不被销毁,就像你的情况一样,除了最后一个字节。

你应该:

strdup()代替赋值。

当你完成了整个结构,使用free()在释放整个结构之前释放字符串

最新更新