在C中使用函数执行子字符串时,字符串解析失败
我在解析C中的字符串时遇到问题。它最终会导致在C中使用函数执行子字符串时,字符串解析失败,c,freertos,C,Freertos,我在解析C中的字符串时遇到问题。它最终会导致硬错误 微控制器:LPC1769, OS:FreeRTOS 10, 工具链:IAR 为了测试,如果我一直发送相同的数据帧(您可以在parseMessage函数的message变量中看到下面的示例), 经过5-6次解析后,一切正常,解析工作与我预期的一样,然后当我向函数发送一个完全相同的字符串时,解析突然陷入HardFault 我在中测试了这个函数。我没有发现任何问题 下面我有两个稍微不同的函数版本,虽然结果是一样的 char *substr3(char
硬错误
微控制器:LPC1769,
OS:FreeRTOS 10,
工具链:IAR
为了测试,如果我一直发送相同的数据帧(您可以在parseMessage
函数的message
变量中看到下面的示例),
经过5-6次解析后,一切正常,解析工作与我预期的一样,然后当我向函数发送一个完全相同的字符串时,解析突然陷入HardFault
我在中测试了这个函数。我没有发现任何问题
下面我有两个稍微不同的函数版本,虽然结果是一样的
char *substr3(char const *input, size_t start, size_t len) {
char *ret = malloc(len+1);
memcpy(ret, input+start, len);
ret[len] = '\0';
return ret;
}
我提取了功能片段,以便更好地进行概述:
(不要注意stripEOL(message);
call,它只是去掉了行尾字符,但你可以在我的gdbonline共享中看到它)
只有数据
变量的长度不同
e、 g.数据-->“347C31323030302D313253330387C33302E30372E323032307C31317C33307C33317C31352D31367C31357C317C57656E6757274”
硬故障调试日志:
拆卸中的LR=0x8667
拆解中的PC=0x2dd0
我感谢贡献者,他们引导我为我的实例找到了解决方案
由于投稿人并没有一个完整的解决方案,而我找到了一个可行的解决方案,所以我最好为将来可能感兴趣的人写一篇文章
由于我是在FreeRTOS 10之上开发我的应用程序,并使用C库中的malloc,显然它至少与我的实现不协调。有人在一些参考资料中说过,你可以在FreeRTOS中使用标准的malloc,因为一些未知的原因,我无法管理自己。如果我增加了堆内存,这可能会有所帮助,我不知道,但我也没有打算这样做
我刚刚放置了这两个包装函数(在一个公共文件中的某个地方),甚至没有更改我的malloc和free调用
创建与内置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的可能副本。请发一封电子邮件。除非分配失败(ret==NULL
),否则不会检查malloc
返回值。…@DavidC.Rankin我认为它不会写入超出ret
的范围,因为start
不会影响ret
@KamilCuk的偏移量,不,它不会重复。它也是我的,但这更像是一个后续行动。@Sener你应该检查malloc
是否成功。@Sener是的,在malloc
和memcpy
之间加上适当的错误处理,这样当ret
为NULL
时,就不会执行写入ret
指向的缓冲区的行。
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);
}
}