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; }
修复说明
- 明确数据类型:指定
torch::kUInt8与OpenCV的CV_8UC3对应,避免类型推断错误。 - 转换内存布局:先基于OpenCV的HWC内存构造Tensor,再通过
permute调整维度顺序为CHW,最后添加批量维度得到NCHW,这是LibTorch处理图像的标准格式,内存访问逻辑完全匹配。 - 非拥有式Tensor注意事项:
torch::from_blob创建的Tensor不拥有内存所有权,需确保cv::Mat对象在Tensor生命周期内有效,这里imgMat在main函数内,生命周期覆盖Tensor,无需额外处理。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

