0

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

//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->buffer 正确拥有一切?

4

3 回答 3

5

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

正如丹尼尔所建议的那样,使用strdup可能是解决问题的最简单方法:

pct->buffer = strdup(string_temp);

只要确保你检查它没有失败。你当然也可以使用mallocthen strcpy

于 2013-05-31T13:33:04.990 回答
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);
于 2013-05-31T13:33:08.163 回答
0

这是问题的根源:

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

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

你应该:

在该行中使用strdup()而不是赋值。

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

于 2013-05-31T13:36:13.903 回答