最后一个字节中的内存损坏

时间:2013-05-31 13:30:02

标签: c

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

//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字节,最后一个字节总是一个损坏的内存。 值为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->缓冲区正确显示所有内容?

3 个答案:

答案 0 :(得分:5)

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

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

pct->buffer = strdup(string_temp);

请确保检查它没有失败。您当然也可以使用malloc然后使用strcpy

答案 1 :(得分:1)

一旦修复了返回指向本地的指针的未定义行为(请参阅Shafik Yaghmour答案),您仍然有未定义的行为:看起来缓冲区没有空终止,因此%s格式说明符读取它,并且仅在找到不相关的\0时停止。

如果你知道缓冲区的长度不能超过8,你可以将其内容复制到pct->len到char缓冲区,然后在结尾处插入一个终结符:

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

答案 2 :(得分:0)

这是问题的根源:

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

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

你应该:

使用strdup()代替该行中的作业。

完成整个结构后,在释放整个结构之前使用free()释放该字符串。