无法修改char*指向地址,函数内buffer地址递增外部不生效求助
问题原因与解决方案
兄弟,这问题其实是C语言里最容易踩的指针坑之一,我来给你掰明白!
核心原因:C语言的参数值传递
你在函数里对buf做递增操作(比如buf++),但外部的指针地址没变化,本质是因为C语言里所有参数都是按值传递的——哪怕是指针类型,传递给函数的也只是原指针变量的一个「副本」。你在函数里修改这个副本的地址,只会改变函数内部的局部变量,对调用者那边的原指针完全没有影响。打个比方:你把家里钥匙复制了一把给朋友,朋友修改了复制的钥匙,你的原钥匙根本不会变。
两种可行的解决方案
方案1:传递指针的指针(最常用)
把函数的buf参数改成双重指针unsigned char **buf,这样你就能在函数里直接修改原指针的地址了。修改后的代码大概是这样:
int mbedtls_net_recv_timeout( void *ctx, unsigned char **buf, size_t len, uint32_t timeout ) { int ret, recv_len; struct timeval tv; fd_set read_fds; int fd = ((mbedtls_net_context *) ctx)->fd; if( fd < 0 ) { // 原有错误处理逻辑 return -1; } // ... 原有接收数据的逻辑,比如调用recv()之类的 recv_len = recv(fd, *buf, len, 0); if(recv_len > 0) { // 忽略第一个字符,修改原指针的地址 *buf += 1; // 注意:这里如果返回接收长度,可能需要减1,根据你的业务需求调整 return recv_len - 1; } // ... 其他逻辑 return ret; }
调用的时候要传指针的地址:
unsigned char my_buffer[512]; unsigned char *buf_ptr = my_buffer; int recv_bytes = mbedtls_net_recv_timeout(ctx, &buf_ptr, sizeof(my_buffer)-1, 5000); // 此时buf_ptr已经指向my_buffer+1的位置了
方案2:返回新的指针地址(适合不想改参数的场景)
如果不想修改函数的参数列表,可以额外返回修改后的指针,不过因为原函数返回的是int(应该是接收的字节数或错误码),所以可以用一个结构体来同时返回状态和新指针,或者用一个输出参数来存新指针。比如:
// 定义一个结构体来返回结果 typedef struct { int status; // 原函数的返回值:接收长度或错误码 unsigned char *new_buf; // 跳过第一个字符后的指针 } RecvResult; RecvResult mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, uint32_t timeout ) { RecvResult res = {0, buf}; int ret, recv_len; struct timeval tv; fd_set read_fds; int fd = ((mbedtls_net_context *) ctx)->fd; if( fd < 0 ) { res.status = -1; return res; } // ... 原有接收逻辑 recv_len = recv(fd, buf, len, 0); if(recv_len > 0) { res.new_buf = buf + 1; res.status = recv_len - 1; } else { res.status = recv_len; } return res; }
调用的时候:
unsigned char my_buffer[512]; RecvResult result = mbedtls_net_recv_timeout(ctx, my_buffer, sizeof(my_buffer)-1, 5000); if(result.status > 0) { // 使用result.new_buf来访问跳过第一个字符的数据 }
额外提醒
如果你的需求只是在使用数据时跳过第一个字符,也可以不用修改指针,直接在外部用buf+1来访问数据——这样更简单,不需要改函数。但如果必须让外部指针直接指向跳过第一个字符的位置,上面的两种方案就很合适啦。
内容的提问来源于stack exchange,提问作者zoueghi okba
相关产品推荐
相关产品推荐

