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,可能还有其他问题很难知道。