一些cpp常见错误报错

Debug Assertion Failed! Expression: _BLOCK_TYPE_IS_VALID

这个错误的产生原因较多,网上查询的结果多为重复删除指针导致的重复释放内存。然而本文遇到的并非如此,本文遇到的情况是clone了一个GitHub开源项目——亚像素提取使用时产生的错误。

环境:
Windows 10
Visual Studio 2017
OpenCV 2.4.10

中间过程:
用Visual Studio打开,去除一些项目自带的用于Linux系统的编译代码,本文实现项目的正常编译。运行时读取了源项目自带的avatar.jpg图片并成功提取边缘,成功计算亚像素点。

错误表现:
报错内容主要是

1
Debug Assertion Failed! Expression: _BLOCK_TYPE_IS_VALID

错误显示如图:

断点到代码内部,亚像素点提取完毕后可以成功断点到函数末尾,然后进入主函数时弹出该窗口。并且不能用try catch抓取。

解决:

  1. 尝试了加入vector变量的reserve函数预留一定空间,发现预留空间过小时将在更前的语句中产生同样错误,预留空间足够大将仍旧在返回主函数时报改错。
  2. 更换了OpenCV版本号,提升到3.x版本,可以正常编译运行通过。

原因:
未知

类型重定义或者使用了未定义类型

原因分析

这种问题往往原因较多,

  1. 确实在代码中重复定义了某个函数或者某个类,同时代码中可能出现了未定义的函数或者类
  2. 文件相互引用时,引用混乱,如果A.h同时被B.h和C引用,但是B.h也被C引用,相当于A.h被C引用多次,出现重定义。引用关系见下图:

解决办法

第一种解决方法很简单,只要去除重定义或者定义好未定义的就可以了。第二种问题解决时分情况

  • 如果可以理清楚关系,并且不需要多重嵌套调用,类似上图中的结构,完全可以取消A.h被C的引用,编译将不出错。
  • 对于部分刚需嵌套调用的情况,如下图所示的调用中,D需要同时使用B.h和C.h中的内容,无法避免重复定义。此时可以在冲突头文件的最上方加入
    1
    #pragma once

这个语句会告诉编译器只编译一次该文件中的内容,从而避免重复编译。或者使用#ifndef和#define,效果相同。

error 0xc0000005: read access violation at: 0xffffffffffffffff, flags=0x0

环境:

Windows 10
QT creator4.11.0
OpenCV 4.5
LibTorch1.7

问题描述:

程序在某段函数中断,无法用try catch抓取错误,中断位置代码为下段中的(*_Pnext)->_Myproxy = nullptr。

1
2
3
4
5
6
7
8
9
10
11
12
inline void _Container_base12::_Orphan_all() noexcept {
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myproxy != nullptr) { // proxy allocated, drain it
_Lockit _Lock(_LOCK_DEBUG);

for (_Iterator_base12** _Pnext = &_Myproxy->_Myfirstiter; *_Pnext != nullptr;
*_Pnext = (*_Pnext)->_Mynextiter) {
(*_Pnext)->_Myproxy = nullptr;
}

_Myproxy->_Myfirstiter = nullptr;
}

同时输出错误有0xc0000005: read access violation at: 0xffffffffffffffff, flags=0x0。

分析原因

根本原因是空图像指针传入libtorch中的torch::from_blob函数引发。表象为Debug模式下使用release版本的opencv读取图片失败。

解决方法

项目模式调整为与库版本一致。

‘torch::nn::Module::clone’ not accessible because ‘BlockImpl’ uses ‘private’ to inherit from ‘torch::nn::Module’

在写ResNet时出现上述错误,由于BasicBlock类是class定义而非struct定义,这就导致c++在处理时,默认父类的其他未override的函数均private,产生错误。

解决方法

  1. 将BasicBlock前的class关键字改为struct关键字,BottleNeck同理。struct默认public,不产生错误。
  2. 继续使用class关键字,但是继承父类时需要在父类前加入public限定。
    1
    2
    3
    4
    //class
    class BlockImpl : public torch::nn::Module{}
    //用struct
    struct BlockImpl : torch::nn::Module{}

class already defined in obj

问题描述

写好ResNet类后,定义resnet18,resnet34等函数时,直接在.h文件下定义将产生该错误。

解决方法

  1. 将函数的声明和定义分开,定义放到.cpp文件则不产生错误。
  2. 不分离,直接在.h的定义前加inline关键字。

Error C2672 ‘torch::nn::AnyModule::make_holder’: no matching overloaded function found

问题描述

使用torch::nn::Sequential时,编译产生7个errors。这是由Sequential里push_back另一个Sequential导致的。

解决办法

这其实是libtorch的一个bug吧算是,c++设计问题,参考c++ sequential in sequential

如非必要,pytorch的代码尽量避免sequential in sequential结构,不然c++加载权重会很麻烦。完全可以用其他结构代替。

长期更新中…