Arduino中char*与const char*类型Serial.print输出异常排查
问题原因及解决方案
核心问题
你在getID()函数里定义的char ID[15]是局部栈变量,函数执行完毕后,栈上的这块内存会被系统回收复用。当你返回ID的指针时,这个指针指向的是已经无效的内存区域,外部调用Serial.println(getID())时,这块内存的数据已经被覆盖,所以打印不出正确内容。而函数内部打印时,函数还在执行,栈内存尚未被回收,因此能正常输出。
解决方法
方法1:使用静态数组
给局部数组加上static修饰,这样内存会分配在全局数据区,函数返回后不会被释放:
char *getID() { static char ID[15]{"123456789ABCDE"}; String str{"EDCBA987654321"}; // 用sizeof(ID)避免数组越界,确保能容纳字符串结束符'\0' str.toCharArray(ID, sizeof(ID)); return ID; }
注意:静态数组是全局唯一的,多次调用函数会覆盖之前的内容,适合你的场景。
方法2:使用全局数组
在函数外部定义全局数组,指针指向的全局内存不会随函数结束被回收:
// 全局数组,内存分配在全局数据区 char ID[15]{"123456789ABCDE"}; char *getID() { String str{"EDCBA987654321"}; str.toCharArray(ID, sizeof(ID)); return ID; }
方法3:直接返回String类型(推荐)
既然代码中已经用到了Arduino的String类,直接返回String更简洁,无需手动管理内存:
String getID() { String str{"EDCBA987654321"}; // 替换为实际获取ID的逻辑 return str; } // loop函数中直接调用 void loop() { Serial.println("print id as the value returned by the \"getID\" function:"); Serial.println(getID()); delay(2000); }
方法4:动态分配内存(谨慎使用)
用malloc在堆上分配内存,但必须手动调用free释放,否则会造成内存泄漏:
char *getID() { String str{"EDCBA987654321"}; // 分配内存时要多留1字节存字符串结束符'\0' char *ID = (char*)malloc(str.length() + 1); if (ID == nullptr) { return nullptr; // 内存分配失败返回空指针 } str.toCharArray(ID, str.length() + 1); return ID; } // loop函数中调用并释放内存 void loop() { Serial.println("print id as the value returned by the \"getID\" function:"); char *id = getID(); if (id != nullptr) { Serial.println(id); free(id); // 必须释放内存,避免泄漏 } delay(2000); }
内容的提问来源于stack exchange,提问作者Juan_David
相关产品推荐
相关产品推荐

