在函数内部错误定位后,从函数中释放返回的指针会导致芯片崩溃
Freeing returned pointer from function after it is malloc'd inside that function causes chip to crash
我在main
内有此调用char* IDQueueString = getIDQueue();
pc.printf("[%9.6f] IDQueue: %srn", t.read(), IDQueueString);
free(IDQueueString);
和getidqueue((;是
char* getIDQueue(void)
{
char* returnString;
char idString[6];
uint8_t pointer = 0;
uint8_t queueLength = 0;
returnString = (char*)malloc((uint32_t)(sizeof(char*)*128));
if(returnString != 0){
pc.printf("[%9.6f] MALLOC: %p, len: %d | LINE %drn", t.read(), returnString, (int)(sizeof(char*)*128), __LINE__);
for(uint8_t i = 0; i < ID_QUEUE_LENGTH; i ++){
if(ReceivedIDs[i].id != -1){
queueLength++;
sprintf(idString, "%d", (int)ReceivedIDs[i].id);
for(uint8_t j = 0; j < strlen(idString); j++){
returnString[pointer] = idString[j];
pointer++;
}
returnString[pointer++] = ',';
returnString[pointer++] = ' ';
}
}
if(queueLength > 0){
returnString[pointer-2] = '.';
returnString[pointer-1] = ' ';
}
if(queueLength == 0){
returnString = (char*)"Empty!";
}
return returnString;
}else{
free(returnString);
error("x1b[31mMALLOC %d!x1b[0mrn", __LINE__);
return (char*)"MALLOC!";
}
}
当它到达二进制中的free(IDQueueString);
时,它将在指令链的某个地方进行:
0x08009d6c: ldr r6, [r1, #8] // *0x2000a208, *0x20008500
0x08009d6e: ldr r0, [r2, #4] // *0x200080d8, *0x1002db40
0x08009d70: cmp r2, r6 // *0x1002db40, *0x2000a208
,但它挂在0x08009d6e
(或者返回到使用
0x08004ffc: b.n 0x8004ffc
我想知道是什么原因导致它这样做?显然,free();
引起了问题,但我无法弄清楚是什么问题。r1
和r2
的值是0x00000000
,r0
为0x00000009
,r6
为0x5DECC885
。
地址0x20000001-0x2001BFFF (112KB)
是SRAM1的范围,0x2001C000-0x2001FFFF (16KB)
是SRAM2的范围。
我不知道该值0x5DECC885
是什么是关于的,但这可能与USB-OCD接口有关。
我假设我免费使用的方式是不正确的,但是由于我将指针返回到malloc();
,为什么我不能以尝试的方式释放返回的指针?
您无法释放任何来自malloc
的事物 - 这样做是"未定义的行为",因此取决于您的运行时的设计方式,实际上发生的是"任何事物"有可能的",它可能会悬挂,崩溃,通过向特朗普签署的普京发出粗鲁的信息或"很好"来开始核战争。
有两种针对您的特定情况的解决方案:
如果malloc
失败,请返回NULL
(如果我们在C 中,则可以选择nullptr
(。如果队列为空,请返回包含字符串"空!"字符串的malloc
'D字符串。(通过使用strcpy
分配或类似(。
另外,只有当您知道队列不包含诸如"Empty!"
或"MALLOC!"
之类的单词时,这才有效:在调用free
之前,请检查是否不是这些字符串之一(使用if(strcmp("Emtpy!", ...) != 0 && strcmp("MALLOC!", ...) != 0) free(...);
。
通过将这些字符串在已知字符串的列表中放入,只需返回该条目,就可以更轻松地使您具有通过比较指针值本身来检查"是已知常数字符串"的函数。[实际上,当您正在处理的内容中存在相同的内容字符串时,这也将起作用,因为内容字符串来自您的代码,它将具有不同的地址] - 它也将有助于避免"哦,哦,我更改了返回的字符串的值,但没有在免费之前进行支票,因为它只是bot用途更改的一个地方。
每当我看到灾难性清单时,我都知道这会很愚蠢。错误的程序逻辑 - 但是编译器必须是错误的:(
是分配函数调用之前的内存。所有当地的杂物都应在返回前释放。它使调试代码更容易(尤其是内存泄漏(。
您有数十亿个与程序交流的方式,但是您选择的方法是最糟糕的方法。首先,将错误(例如失败的mallocs(与应用程序异常(如空名称中的空名(分开是一件好事。我本人会使此函数返回int(例如,负面的int作为系统错误,如果可以的话,则为零,而对于应用程序异常,则可以更轻松地处理它们,并且可以通过指针返回指针。但是,您想在功能中进行malloc(并且不自由( -
if((resultCode = getIDQueue(& IDQueueString) >= 0)
{
// do something (you can have another switch here to deal with application exceptions like empty name for example)
free(IDQueueString);
}
else
{
switch (resultCode)
{
case -1:
// do something malloc failed
break:
case -2:
//deal with another error
break;
//...... etc etc
default:
// ----
break;
}
}
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针