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

为何C传栈字符串给Rust动态库会触发munmap_chunk错误?

问题描述

我用Rust编写了一个对外暴露的C兼容函数listen,它接收*const c_char类型参数并转换为String类型,代码如下:

#[no_mangle]
pub extern "C" fn listen(addr: *const c_char) {
    unsafe {
        let addr_str = {
            let cstr = CStr::from_ptr(addr);
            let bytes = cstr.to_bytes();
            String::from_raw_parts(bytes.as_ptr() as *mut u8, bytes.len(), bytes.len())
        };
    }
}

在C程序中,直接传入命令行参数argv[1]时,程序会抛出munmap_chunk(): invalid pointer错误;但通过malloc在堆上分配内存复制该参数内容后传入,程序可正常运行。

出错的C代码:

#include "xxx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

// input: address
int main(int argc, char *argv[]) {
  if (argc != 2) {
    printf("Usage %s <listen_addr>\n", argv[0]);
    return -1;
  }

  const char *addr = argv[1];

  listen(addr);

  return 0;
}

正常运行的C代码:

int main(int argc, char *argv[]) {
  if (argc != 2) {
    printf("Usage %s <listen_addr>\n", argv[0]);
    return -1;
  }

  const char *addr = argv[1];

  int addr_len = strlen(addr) + 1;

  char *addr_buffer = (char *)malloc(addr_len);
  strcpy(addr_buffer, addr);

  listen(addr_buffer);

  return 0;
}

请问为何传递栈内存字符串会触发错误,堆内存字符串可正常工作?


问题原因

核心问题出在String::from_raw_parts的使用逻辑上:

  • 这个Rust函数要求传入的指针必须是由Rust内存分配器分配、且可被安全释放的内存地址。当addr_str离开作用域时,Rust会自动调用自身分配器释放这块内存。
  • argv[1]指向的内存是操作系统在程序启动时分配的,属于进程的静态/栈内存区域,既不属于Rust分配器管理,也不能被Rust的释放逻辑操作。Rust尝试释放不属于它管辖的内存,直接触发munmap_chunk(): invalid pointer这类内存错误。
  • 用malloc分配的堆内存,虽然是C标准库分配的,但大多数场景下Rust默认全局分配器是对C标准库malloc/free的封装,二者内存管理逻辑兼容,因此Rust可以安全释放这块内存,程序就能正常运行。

此外,你的Rust代码还存在隐藏风险:

  • CStr::to_bytes()返回的是不含末尾\0的字节切片,将其const指针强制转为mut指针的操作不安全——如果原内存是只读的(比如argv[1]通常是只读区域),后续若String尝试修改内容,会触发未定义行为。

正确的实现方式:
通过复制原字符串内容到Rust管理的内存中,彻底规避内存所有权冲突:

#[no_mangle]
pub extern "C" fn listen(addr: *const c_char) {
    unsafe {
        let cstr = CStr::from_ptr(addr);
        // 转换为Rust字符串并复制到新内存
        let addr_str = cstr.to_str().unwrap_or_default().to_string();
        // 后续使用addr_str即可
    }
}

内容的提问来源于Stack Exchange,提问作者ChrisFisher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 09:27:43