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
相关产品推荐
相关产品推荐

