在 C 中使用执行子字符串的函数时字符串解析失败
String parsing failes when using a function doing substring in C
我在用 C 解析字符串时遇到问题。它最终会导致 HardFault
。
单片机:LPC1769,
OS: FreeRTOS 10,
工具链:IAR
为了测试,如果我一直发送相同的数据帧(您可以在 parseMessage
函数的 message
变量中看到下面的示例),
解析 5-6 次后一切正常,解析工作如我所料,然后当我向函数发送另一个完全相同的字符串时突然陷入 HardFault
。
我测试了OnlineGDB中的功能。我没有发现任何问题。
虽然结果相同,但我在下面有几个版本略有不同的函数;
char *substr3(char const *input, size_t start, size_t len) {
char *ret = malloc(len+1);
memcpy(ret, input+start, len);
ret[len] = '[=10=]';
return ret;
}
我已经提取了功能部分以便更好地概述:
(不用注意stripEOL(message);
调用,它只是去掉行尾字符,但是你可以在我的gdbonline分享中看到它)
void parseMessage(char * message){
//char* message= "7E00002A347C31323030302D3132353330387C33302E30372E323032307C31317C33307C33317C31352D31367C31357C317C57656E67657274880D";
// Parsing the frame
char* start;
char* len;
char* cmd;
char* data;
char* chksum;
char* end;
stripEOL(message);
unsigned int messagelen = strlen(message);
start = substr3(message, 0, 2);
len = substr3(message, 2, 4);
cmd = substr3(message, 6, 2);
data = substr3(message, 8, messagelen-8-4);
chksum = substr3(message, messagelen-4, 2);
end = substr3(message, messagelen-2, 2);
}
只有 data
变量的长度不同。
例如数据 --> "347C31323030302D3132353330387C33302E30372E323032307C31317C33307C33317C31352D31367C31357C317C57656E67657274"
HardFault 调试日志:
LR = 0x8667 反汇编
反汇编中的 PC = 0x2dd0
感谢贡献者,是他们引导我为我的实例找到了解决方案。
由于贡献者没有一个完整的解决方案,而我找到了一个可行的解决方案,我最好为将来可能感兴趣的人写作。
由于我是在 FreeRTOS 10 之上开发我的应用程序并使用 C 库中的 malloc,显然它至少没有配合我的实现。在某些资源中提到,您可以在 FreeRTOS 中使用标准 malloc,但由于某些未知原因我无法管理自己。这可能是一个帮助,如果我增加了堆内存,我不知道,但我也没有打算这样做。
我只是放置了两个包装器函数(在公共文件中的某处),甚至没有更改我的 malloc 和 free 调用。;
创建使用 built-in FreeRTOS 堆的 malloc/free 函数非常简单。我们只是包装 pvPortMalloc/pvPortFree 调用:
void* malloc(size_t size)
{
void* ptr = NULL;
if(size > 0)
{
// We simply wrap the FreeRTOS call into a standard form
ptr = pvPortMalloc(size);
} // else NULL if there was an error
return ptr;
}
void free(void* ptr)
{
if(ptr)
{
// We simply wrap the FreeRTOS call into a standard form
vPortFree(ptr);
}
}
请注意:您不能将其用于堆模式 #1,但不能用于其他堆模式(2、3、4 和 5)。
我建议开始使用 portable/MemMang/heap_4.c
我在用 C 解析字符串时遇到问题。它最终会导致 HardFault
。
单片机:LPC1769, OS: FreeRTOS 10, 工具链:IAR
为了测试,如果我一直发送相同的数据帧(您可以在 parseMessage
函数的 message
变量中看到下面的示例),
解析 5-6 次后一切正常,解析工作如我所料,然后当我向函数发送另一个完全相同的字符串时突然陷入 HardFault
。
我测试了OnlineGDB中的功能。我没有发现任何问题。
虽然结果相同,但我在下面有几个版本略有不同的函数;
char *substr3(char const *input, size_t start, size_t len) {
char *ret = malloc(len+1);
memcpy(ret, input+start, len);
ret[len] = '[=10=]';
return ret;
}
我已经提取了功能部分以便更好地概述:
(不用注意stripEOL(message);
调用,它只是去掉行尾字符,但是你可以在我的gdbonline分享中看到它)
void parseMessage(char * message){
//char* message= "7E00002A347C31323030302D3132353330387C33302E30372E323032307C31317C33307C33317C31352D31367C31357C317C57656E67657274880D";
// Parsing the frame
char* start;
char* len;
char* cmd;
char* data;
char* chksum;
char* end;
stripEOL(message);
unsigned int messagelen = strlen(message);
start = substr3(message, 0, 2);
len = substr3(message, 2, 4);
cmd = substr3(message, 6, 2);
data = substr3(message, 8, messagelen-8-4);
chksum = substr3(message, messagelen-4, 2);
end = substr3(message, messagelen-2, 2);
}
只有 data
变量的长度不同。
例如数据 --> "347C31323030302D3132353330387C33302E30372E323032307C31317C33307C33317C31352D31367C31357C317C57656E67657274"
HardFault 调试日志:
LR = 0x8667 反汇编
反汇编中的 PC = 0x2dd0
感谢贡献者,是他们引导我为我的实例找到了解决方案。
由于贡献者没有一个完整的解决方案,而我找到了一个可行的解决方案,我最好为将来可能感兴趣的人写作。
由于我是在 FreeRTOS 10 之上开发我的应用程序并使用 C 库中的 malloc,显然它至少没有配合我的实现。在某些资源中提到,您可以在 FreeRTOS 中使用标准 malloc,但由于某些未知原因我无法管理自己。这可能是一个帮助,如果我增加了堆内存,我不知道,但我也没有打算这样做。
我只是放置了两个包装器函数(在公共文件中的某处),甚至没有更改我的 malloc 和 free 调用。;
创建使用 built-in FreeRTOS 堆的 malloc/free 函数非常简单。我们只是包装 pvPortMalloc/pvPortFree 调用:
void* malloc(size_t size)
{
void* ptr = NULL;
if(size > 0)
{
// We simply wrap the FreeRTOS call into a standard form
ptr = pvPortMalloc(size);
} // else NULL if there was an error
return ptr;
}
void free(void* ptr)
{
if(ptr)
{
// We simply wrap the FreeRTOS call into a standard form
vPortFree(ptr);
}
}
请注意:您不能将其用于堆模式 #1,但不能用于其他堆模式(2、3、4 和 5)。 我建议开始使用 portable/MemMang/heap_4.c