C语言函数赋值指针后主函数内容乱码,地址却正常问题排查
问题分析与解决思路
核心问题:访问已释放的栈内存
你遇到的乱码问题本质是栈内存的生命周期陷阱:在getPage函数里定义的char teststring[]是局部栈变量,它的内存仅在函数执行期间有效。当getPage执行完毕返回后,函数的栈帧会被销毁,这块内存会被后续的系统调用或函数执行覆盖,所以主函数里再访问这个地址,拿到的就是被覆盖后的垃圾数据,也就是你看到的乱码。
另外你的代码还有几个额外问题需要修正:
- 野指针非法访问:主函数里
char* buffer;是未初始化的野指针,直接打印*buffer会触发未定义行为(你控制台里的buffer address in main: 99就是随机的垃圾值)。 - 错误使用
sizeof:sizeof(buffer)得到的是指针本身的大小(在32位ESP32系统里是4字节),不是字符串的长度,要获取字符串长度应该用strlen(buffer)。 - 地址打印格式错误:打印指针地址应该用
%p格式符,而不是%d,%d是用于整数的,在64位系统里会导致地址截断。
解决思路
方法1:使用动态内存分配(推荐用于可变内容场景)
如果后续要从SPIFFS读取真实文件内容(长度不固定),最好用动态内存分配,让getPage负责分配内存,主函数使用完后释放:
修改后的getPage函数:
#include <esp_system.h> #include <string.h> #include <stdlib.h> // 引入malloc/free头文件 esp_err_t getPage(char** buffer, char* path) { // 先检查传入的指针本身是否有效 if (buffer == NULL) { return ESP_ERR_INVALID_ARG; } if (strcmp(path, "abc") == 0) { const char* test_content = "This is my string that represents the buffer for my file."; size_t content_len = strlen(test_content) + 1; // +1 是为了存储字符串终止符'\0' // 分配内存 *buffer = (char*)malloc(content_len); if (*buffer == NULL) { return ESP_ERR_NO_MEM; // 内存分配失败返回错误码 } // 复制内容到分配的内存 strcpy(*buffer, test_content); ESP_LOGI("TESTING", "buffer in function is:%s address:%p", *buffer, *buffer); } return ESP_OK; }
主函数修改:
void app_main() { //... char* buffer = NULL; // 初始化为NULL,避免野指针 ESP_LOGI("TESTING", "buffer pointer in main: %p", buffer); esp_err_t ret = getPage(&buffer, "abc"); if (ret == ESP_OK && buffer != NULL) { ESP_LOGI("TESTING", "buffer pointer in main after getpage: %p", buffer); ESP_LOGI("TESTING", "buffer in main after getpage is:%s", buffer); ESP_LOGI("TESTING", "buffer length in main after getpage is:%zu", strlen(buffer)); free(buffer); // 必须释放内存,避免内存泄漏 buffer = NULL; // 防止悬空指针 } //... }
方法2:使用静态变量(仅适用于固定内容场景)
如果你的字符串内容是固定不变的,可以把teststring声明为static,这样它会存储在静态内存区,函数返回后不会被释放:
esp_err_t getPage(char** buffer, char* path) { if (buffer == NULL) { return ESP_ERR_INVALID_ARG; } if (strcmp(path, "abc") == 0) { static char teststring[] = "This is my string that represents the buffer for my file."; *buffer = teststring; ESP_LOGI("TESTING", "buffer in function is:%s address:%p", *buffer, *buffer); } return ESP_OK; }
这种方法不需要手动释放内存,但要注意静态变量是全局唯一的,多次调用getPage会返回同一个内存地址,如果后续要修改内容会影响所有调用者。
额外注意事项
- 永远不要返回局部栈变量的地址,这是C语言里的常见陷阱。
- 处理动态内存时,一定要记得在使用完后释放,避免内存泄漏。
- 打印指针地址时统一使用
%p格式符,保证跨平台兼容性。
内容的提问来源于stack exchange,提问作者Jokel64
相关产品推荐
相关产品推荐

