std::string作为全局变量时socket调用send返回Bad address异常问题
异常产生原因
核心问题是send函数调用的长度参数不合理,触发了未定义行为,在不同内存布局下表现出不同的结果:
- 你代码中
send(connfd, temp, MAXTEXT, 0)的第三个参数写死为MAXTEXT,但cmdline.c_str()返回的指针指向的有效可读内存仅为cmdline.size() + 1字节(字符串内容+末尾结束符)。当MAXTEXT大于这个长度时,send会尝试读取指针后超出有效范围的内存,一旦访问到未映射、不可读的内存地址,就会触发EFAULT错误,返回-1并提示Bad address。 - 全局
std::string变量存储在进程的全局数据段,其后方的内存大概率是未分配/不可读的,越界访问直接触发错误;而局部std::string存储在栈空间,栈上下的内存大多是已映射可读取的,越界读不会立刻触发内存访问错误,因此看起来运行正常。调试模式下编译器会额外插入调试填充内存,填充区域是合法可访问的,因此也不会触发错误。这两种情况本质都存在内存越界访问的隐患,只是未触发报错而已。
解决方法
- 修正
send的长度参数,仅发送实际的有效内容长度:
把原有代码
auto n = send(connfd, temp, MAXTEXT, 0);
修改为
auto n = send(connfd, temp, cmdline.size(), 0);
如果业务需要把字符串末尾的\0也一起发送,可以把长度改为cmdline.size() + 1。
2. 补充send返回值的校验和补发逻辑:send在内核发送缓冲区不足时可能返回小于预期长度的有效值,并非错误,需要循环发送剩余内容,避免数据丢失。
内容的提问来源于stack exchange,提问作者isudfv
相关产品推荐
相关产品推荐

