记录一个没有碎片堆的字节数组
Log an array of bytes without fragmenting heap
我正在 运行正在记录到我的 uart 端口的 STM32 芯片上的一些代码。
我很难找到记录字节数组的正确方法。我写了这个函数:
static void LogBytes(uint8_t *data, uint32_t length)
{
char message[length*6]={};
static char byteRepresentation[6];
for (uint32_t i=0; i<length; i++)
{
sprintf(byteRepresentation, "0x%02X ", data[i] & 0xFF);
strncat(message, byteRepresentation, 6);
}
logger.WriteDebug(LoggingCategorySio, message);
}
但是当我 运行 这样做时,我最终会遇到硬故障(很难排除故障,但我怀疑它是由堆 corruption/fragementation 引起的)。
我认为问题是由 strncat
引起的(对 this answer 的评论警告我可能遇到的一些问题)。我还读到尽可能远离 malloc / free。所以我正在努力在堆栈上做尽可能多的事情。
我是否遗漏了这段代码中的一些愚蠢的错误?还是应该完全不同?
来自评论:
"there are other, quicker and more efficient alternatives (such as
strcpy() or memmove()) that could be used instead. Pretty much
whatever the question of 'what should I use', strncat() is not the
answer"
使用strcpy / memmove 确实更好吗?还是他们实际上更多地依赖 malloc / free,因此我应该避免更多?
如果问题最终是由堆过度使用引起的(来自 strncat
),那么您可以尝试使用 sprintf
中的 return 附加到字符串的实现作为你的建筑。
static void LogBytes(uint8_t *data, uint32_t length)
{
char message[length*6];
memset(message, 0, length*6);
size_t message_offset = 0;
for (uint32_t i=0; i<length; i++)
{
int ret = sprintf(message + message_offset, "0x%02X ", data[i] & 0xFF);
if (ret > 0){
message_offset += ret;
} else {
//TODO react however you want to sprintf error
break;
}
}
logger.WriteDebug(LoggingCategorySio, message);
}
但是,堆栈溢出也可能会出现问题。如果这是问题所在,那么这个可变长度数组 char message[length*6];
可能是打印超大数组时出现硬故障的罪魁祸首。
我正在 运行正在记录到我的 uart 端口的 STM32 芯片上的一些代码。
我很难找到记录字节数组的正确方法。我写了这个函数:
static void LogBytes(uint8_t *data, uint32_t length)
{
char message[length*6]={};
static char byteRepresentation[6];
for (uint32_t i=0; i<length; i++)
{
sprintf(byteRepresentation, "0x%02X ", data[i] & 0xFF);
strncat(message, byteRepresentation, 6);
}
logger.WriteDebug(LoggingCategorySio, message);
}
但是当我 运行 这样做时,我最终会遇到硬故障(很难排除故障,但我怀疑它是由堆 corruption/fragementation 引起的)。
我认为问题是由 strncat
引起的(对 this answer 的评论警告我可能遇到的一些问题)。我还读到尽可能远离 malloc / free。所以我正在努力在堆栈上做尽可能多的事情。
我是否遗漏了这段代码中的一些愚蠢的错误?还是应该完全不同?
来自评论:
"there are other, quicker and more efficient alternatives (such as strcpy() or memmove()) that could be used instead. Pretty much whatever the question of 'what should I use', strncat() is not the answer"
使用strcpy / memmove 确实更好吗?还是他们实际上更多地依赖 malloc / free,因此我应该避免更多?
如果问题最终是由堆过度使用引起的(来自 strncat
),那么您可以尝试使用 sprintf
中的 return 附加到字符串的实现作为你的建筑。
static void LogBytes(uint8_t *data, uint32_t length)
{
char message[length*6];
memset(message, 0, length*6);
size_t message_offset = 0;
for (uint32_t i=0; i<length; i++)
{
int ret = sprintf(message + message_offset, "0x%02X ", data[i] & 0xFF);
if (ret > 0){
message_offset += ret;
} else {
//TODO react however you want to sprintf error
break;
}
}
logger.WriteDebug(LoggingCategorySio, message);
}
但是,堆栈溢出也可能会出现问题。如果这是问题所在,那么这个可变长度数组 char message[length*6];
可能是打印超大数组时出现硬故障的罪魁祸首。