You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言函数赋值指针后主函数内容乱码,地址却正常问题排查

问题分析与解决思路

核心问题:访问已释放的栈内存

你遇到的乱码问题本质是栈内存的生命周期陷阱:在getPage函数里定义的char teststring[]是局部栈变量,它的内存仅在函数执行期间有效。当getPage执行完毕返回后,函数的栈帧会被销毁,这块内存会被后续的系统调用或函数执行覆盖,所以主函数里再访问这个地址,拿到的就是被覆盖后的垃圾数据,也就是你看到的乱码。

另外你的代码还有几个额外问题需要修正:

  1. 野指针非法访问:主函数里char* buffer;是未初始化的野指针,直接打印*buffer会触发未定义行为(你控制台里的buffer address in main: 99就是随机的垃圾值)。
  2. 错误使用sizeof:sizeof(buffer)得到的是指针本身的大小(在32位ESP32系统里是4字节),不是字符串的长度,要获取字符串长度应该用strlen(buffer)。
  3. 地址打印格式错误:打印指针地址应该用%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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:33:40