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

C++中使用LibTorch访问at::Tensor时出现段错误求助

问题:OpenCV与LibTorch代码段运行崩溃

我编写了一段使用OpenCV和LibTorch的简单代码,但无法正常运行。代码如下:

#include <iostream>
#include <torch/script.h>
#include <opencv2/core/core.hpp>

int main() {
    cv::Mat imgMat = cv::Mat::zeros(640, 640, CV_8UC3);
    at::Tensor tensorImg = torch::from_blob(imgMat.data, {1, imgMat.rows, imgMat.cols, imgMat.channels()});
    std::cout << tensorImg << "\n";  // 崩溃点

    return 0;
}

尝试用clang编译并启用UndefinedBehaviorSanitizer后,得到以下错误信息:

UndefinedBehaviorSanitizer:DEADLYSIGNAL
==11549==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x7fffde2fa000 (pc 0x7fffe4039d08 bp 0x7fffdd7b4ed0 sp 0x7fffdd7b4e20 T11570)
==11549==The signal is caused by a READ memory access.
UndefinedBehaviorSanitizer:DEADLYSIGNAL
UndefinedBehaviorSanitizer:DEADLYSIGNAL
    #0 0x7fffe4039d08 in void c10::function_ref<void (char**, long const*, long, long)>::callback_fn<auto at::TensorIteratorBase::loop_2d_from_1d<at::native::AVX2::copy_kernel(at::TensorIterator&, bool)::'lambda'()::operator()() const::'lambda10'()::operator()() const::'lambda'()::operator()() const::'lambda12'()::operator()() const::'lambda'(char**, long const*, long)>(at::native::AVX2::copy_kernel(at::TensorIterator&, bool)::'lambda'()::operator()() const::'lambda10'()::operator()() const::'lambda'()::operator()() const::'lambda12'()::operator()() const::'lambda'(char**, long const*, long) const&)::'lambda'(char**, long const*, long, long)>(long, char**, long const*, long, long) (/home/dani/Desktop/test/build/libtorch/lib/libtorch_cpu.so+0x54bed08) (BuildId: e03155c98263c3ef83236051d8610270872897af)
    #1 0x7fffdfecf96f in at::TensorIteratorBase::serial_for_each(c10::function_ref<void (char**, long const*, long, long)>, at::Range) const (/home/dani/Desktop/test/build/libtorch/lib/libtorch_cpu.so+0x135496f) (BuildId: e03155c98263c3ef83236051d8610270872897af)
    #2 0x7fffdfecfb2d in void at::internal::invoke_parallel<at::TensorIteratorBase::for_each(c10::function_ref<void (char**, long const*, long, long)>, long)::'lambda'(long, long)>(long, long, long, at::TensorIteratorBase::for_each(c10::function_ref<void (char**, long const*, long, long)>, long)::'lambda'(long, long) const&) (._omp_fn.0) (/home/dani/Desktop/test/build/libtorch/lib/libtorch_cpu.so+0x1354b2d) (BuildId: e03155c98263c3ef83236051d8610270872897af)
    #3 0x7fffde41696d  (/home/dani/Desktop/test/build/libtorch/lib/libgomp-52f2fd74.so.1+0x1696d) (BuildId: 9afb2d23e5127e68ba5ef6031eefc9d25b9b672b)
    #4 0x7fffde79db42 in start_thread nptl/./nptl/pthread_create.c:442:8
    #5 0x7fffde82f9ff  misc/../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

UndefinedBehaviorSanitizer can not provide additional info.
SUMMARY: UndefinedBehaviorSanitizer: SEGV (/home/dani/Desktop/test/build/libtorch/lib/libtorch_cpu.so+0x54bed08) (BuildId: e03155c98263c3ef83236051d8610270872897af) in void c10::function_ref<void (char**, long const*, long, long)>::callback_fn<auto at::TensorIteratorBase::loop_2d_from_1d<at::native::AVX2::copy_kernel(at::TensorIterator&, bool)::'lambda'()::operator()() const::'lambda10'()::operator()() const::'lambda'()::operator()() const::'lambda12'()::operator()() const::'lambda'(char**, long const*, long)>(at::native::AVX2::copy_kernel(at::TensorIterator&, bool)::'lambda'()::operator()() const::'lambda10'()::operator()() const::'lambda'()::operator()() const::'lambda12'()::operator()() const::'lambda'(char**, long const*, long) const&)::'lambda'(char**, long const*, long, long)>(long, char**, long const*, long, long)
==11549==ABORTING

问题原因与修复方案

核心问题

  • 内存布局不匹配:OpenCV的cv::Mat默认采用行优先(row-major)存储,维度为HWC(高、宽、通道);而你直接构造的Tensor是NHWC格式,但LibTorch默认对张量的内存访问逻辑更适配NCHW(批量、通道、高、宽)格式,且未明确指定内存步长,导致打印Tensor时内存越界访问。
  • 数据类型未明确指定:torch::from_blob未指定数据类型,可能导致类型推断错误,进一步引发内存访问问题。

修复后的代码

#include <iostream>
#include <torch/script.h>
#include <opencv2/core/core.hpp>

int main() {
    cv::Mat imgMat = cv::Mat::zeros(640, 640, CV_8UC3);
    
    // 先构造HWC格式Tensor,再转为LibTorch常用的NCHW格式
    at::Tensor tensorImg = torch::from_blob(imgMat.data, 
                                            {imgMat.rows, imgMat.cols, imgMat.channels()}, 
                                            torch::kUInt8)
                            .permute({2, 0, 1})  // HWC → CHW
                            .unsqueeze(0);       // 添加批量维度 → NCHW
    
    std::cout << tensorImg << "\n";

    return 0;
}

修复说明

  1. 明确数据类型:指定torch::kUInt8与OpenCV的CV_8UC3对应,避免类型推断错误。
  2. 转换内存布局:先基于OpenCV的HWC内存构造Tensor,再通过permute调整维度顺序为CHW,最后添加批量维度得到NCHW,这是LibTorch处理图像的标准格式,内存访问逻辑完全匹配。
  3. 非拥有式Tensor注意事项:torch::from_blob创建的Tensor不拥有内存所有权,需确保cv::Mat对象在Tensor生命周期内有效,这里imgMat在main函数内,生命周期覆盖Tensor,无需额外处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:55:21