C 最后一个字节内存损坏

C 最后一个字节内存损坏,c,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

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

//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正确地保存所有内容?

看起来您正在返回指向未定义行为的局部变量的指针,
string\u temp
是返回\u数据包的
函数的局部变量,退出该函数后将不存在

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

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

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

看起来您正在返回一个指向未定义行为的局部变量的指针,
string\u temp
是返回\u数据包的
函数的局部变量,退出该函数后将不存在

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

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

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

一旦您修复了返回本地指针的未定义行为(请参见Shafik Yaghmour的答案),您仍然有未定义的行为:缓冲区似乎不是null terminated的,因此
%s
格式说明符读取它,仅当它发现不相关的
\0
时停止

如果您知道缓冲区的长度不能超过8,则可以将其内容复制到char缓冲区中的
pct->len
,然后在末尾插入终止符:

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);

一旦修复了返回本地指针的未定义行为(请参见Shafik Yaghmour答案),您仍然有未定义的行为:缓冲区似乎不是null terminated,因此
%s
格式说明符将读取它,并且仅当它找到不相关的
\0
时才会停止

如果您知道缓冲区的长度不能超过8,则可以将其内容复制到char缓冲区中的
pct->len
,然后在末尾插入终止符:

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);

这就是问题的根源:

pct->buffer = strdup(string_temp);
pct->buffer = (unsigned char *)string_temp;
“string_temp”在堆栈上分配。当函数返回时,它会在稍后的某个地方被销毁,或者不会被销毁,就像您的例子中一样,除了最后一个字节

你应该:

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


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

这就是问题的根源:

pct->buffer = strdup(string_temp);
pct->buffer = (unsigned char *)string_temp;
“string_temp”在堆栈上分配。当函数返回时,它会在稍后的某个地方被销毁,或者不会被销毁,就像您的例子中一样,除了最后一个字节

你应该:

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


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

是否为函数中的“pct”分配内存。这只是一个提问提示:您通常应该提供一个。否则,我们无法确定您发布的代码片段是否确实包含问题。您已删除导致问题的确切行。不管“更多的初始化”是什么,它做了一些非常非法的事情。请下次显示所有相关代码,包括错误的位。您是否为函数中的“pct”分配内存。只是一个提问提示:您通常应该提供一个示例,以便人们能够最好地理解您的问题。否则,我们无法确定您发布的代码片段是否确实包含问题。您已删除导致问题的确切行。不管“更多的初始化”是什么,它做了一些非常非法的事情。请下次显示所有相关代码,包括错误的位。@Shafik Yaghmour:如果是未定义的行为,为什么只有最后一个字符被损坏?那么我应该如何修复上面的错误,以便正确地获得数据包的值?@xambo“未定义的行为”的意思是:行为未定义。因此,(程序员)没有理由认为字节被破坏。也许如果你明天运行它,所有的字节都会被删除。它是未定义的。@xambo它是未定义的行为,因此您对结果没有任何期望。我还更新了一个解决方案,没有SSCCE可能还有其他问题,这很难知道。@Shafik Yaghmour:如果是未定义的行为,为什么只有最后一个字符被损坏?那么我应该如何修复上面的错误,以便正确地获得数据包的值?@xambo“未定义的行为”的意思是:行为未定义。因此,(程序员)没有理由认为字节被破坏。也许如果你明天运行它,所有的字节都会被删除。它是未定义的。@xambo它是未定义的行为,因此您对结果没有任何期望。我还更新了一个解决方案,如果没有SSCCE,可能还有其他问题很难知道。