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

C语言传递Buffer至写入函数后输出Null,指针传递是否有误?

问题分析与解决方案

核心问题

你遇到的问题根源是C语言的指针值传递特性:当你把buffer传给pack_message函数时,传递的是指针的副本。子函数里对buffer的赋值(比如buffer = malloc(...))只会修改这个局部副本,主函数中的原buffer变量完全没变化,依然是NULL,所以printf输出(null)。

修改方案(两种可选)

方案一:使用双重指针(指针的指针)

通过传递指针的地址,让子函数直接修改主函数中的指针变量:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char *header = "testhd";

void pack_message(char *body, char **buffer)
{
    size_t body_size, msg_size, buffer_size;
    char hex_size[11];
    
    body_size = strlen(body);
    snprintf(hex_size, 11, "0x%x", (unsigned int)body_size);
    // 替换硬编码16,计算实际需要的长度更可靠
    msg_size = strlen(header) + strlen(hex_size) + body_size;
    buffer_size = msg_size + 1;
    
    if (!*buffer){
        *buffer = malloc(buffer_size);
    }else{
        *buffer = realloc(*buffer, buffer_size);
    }
    
    // 增加内存分配失败的检查,避免空指针操作
    if (!*buffer) {
        perror("malloc/realloc failed");
        return;
    }
    
    memset(*buffer, 0, buffer_size);
    
    // 第一次用strcpy更直观,空buffer用strcat也可,但strcpy语义更清晰
    strcpy(*buffer, header);
    strcat(*buffer, hex_size);
    strcat(*buffer, body);
}

int main(){
    char *buffer = NULL;
    char *body = "testmsg";
    pack_message(body, &buffer); // 传递buffer的地址
    if (buffer) {
        printf("%s", buffer);
        free(buffer); // 记得释放动态分配的内存,避免泄漏
    }
    return 0;
}

方案二:让函数返回新指针

将pack_message改为返回char*类型,直接返回分配好的内存地址:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char *header = "testhd";

char* pack_message(char *body, char *buffer)
{
    size_t body_size, msg_size, buffer_size;
    char hex_size[11];
    
    body_size = strlen(body);
    snprintf(hex_size, 11, "0x%x", (unsigned int)body_size);
    msg_size = strlen(header) + strlen(hex_size) + body_size;
    buffer_size = msg_size + 1;
    
    if (!buffer){
        buffer = malloc(buffer_size);
    }else{
        buffer = realloc(buffer, buffer_size);
    }
    
    if (!buffer) {
        perror("malloc/realloc failed");
        return NULL;
    }
    
    memset(buffer, 0, buffer_size);
    
    strcpy(buffer, header);
    strcat(buffer, hex_size);
    strcat(buffer, body);
    
    return buffer;
}

int main(){
    char *buffer = NULL;
    char *body = "testmsg";
    buffer = pack_message(body, buffer); // 接收返回的指针
    if (buffer) {
        printf("%s", buffer);
        free(buffer);
    }
    return 0;
}

额外注意事项

  • 原代码中msg_size = 16 + body_size是硬编码,替换为计算header和hex_size的实际长度,能避免内存浪费或长度不足的问题。
  • 动态内存分配后必须检查是否成功,防止空指针引发崩溃。
  • 使用完动态分配的内存后一定要调用free,避免内存泄漏。
  • snprintf格式化size_t类型的body_size时,转成unsigned int可避免符号相关的编译警告。

内容的提问来源于stack exchange,提问作者mv_p

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 09:27:22