C++ 动态分配数组空间,以及opencv中Mat类的初始化

原创 2016年08月29日 10:04:33

在C++中,如果想要申请动态数组,必须要用动态分配的方式。

int **matrix=new int*[num_of_rows];
for(int i=0;i<num_of_rows;i++){
    int *row=new int[num_of_cols];
    //在这里对这一行进行赋值
    for(int j=0;j<num_of_cols;j++){
        row[j]=j;
    }
    matrix[i]=row;
}

这样,就实现了一个二维数组空间的申请,以及赋值。
但是在实际使用中,可能会因为动态申请的空间过大,系统在申请空间时失败。此时会抛出Exception: fail to allocate memory block。那么,我们需要用一种方法告诉系统,如果申请空间失败,那就继续去申请,别来抛出异常。
C++ Dynamic Programming中,介绍了一种避免异常的方式,使用关键字:nothrow

int *foo = new (nothrow) int [5];

这样,在申请空间时,如果没有申请成功,new的返回值是null,如果申请成功,返回值是申请到的空间的指针。那么我们就可以通过if语句判断是否空间申请成功,然后告诉计算机如何执行。
于是我这样设计了申请数组的代码,如果没有申请成功,则一直去申请,直到申请成功为止:

int *mat = new (nothrow) int [1000];
while(!mat){
    mat = new (nothrow) int [1000];
}
//程序如果能运行到这里,说明空间已经申请成功,可以对数据进行操作了
for(int i=0;i<1000;i++){
    mat[i]=i;
}

C++ Dynamic Programming中说,这种方式是一种不太有效率的方法,但是简单有效。

Exception比较高效,但是在实际编程中,总是跳出Exception,好烦,索性设计成暴力申请空间的方式。这个问题有待深入研究,数据量大了,内存管理也是一门学问。

补充:最近做项目,用到opencv。Mat类有这个初始化函数:

Mat<T>(int rows, int cols,int type, T * data)

想要初始化Mat类型,可以通过数组实现。一种方式是对Mat的元素挨个进行赋值(方法一),另一种方式是将数组整体赋值(方法二)。还有一种貌似可行但实际不行的方法,也用的是二维数组(方法三)。
方法一:挨个赋值:

Mat mt(rows,cols,CV_32FC1);
for(int i=0;i<rows;i++){
    for(int j=0;j<cols;j++){
        mt.at<float>(i,j)=i*j;
    }
}

方法二:利用数组整体赋值:

float *data =  new float[rows*cols];
for(int i=0;i<rows;i++){
    for(int j=0;j<cols;j++){
        data[i*cols+j]=i*j;
    }
}
Mat mt(rows,cols,CV_32FC1,data);

方法三(不可行):利用不连续的数组空间进行Mat的初始化:

float **data = new float*[rows];
float *row;
for(int i=0;i<rows;i++){
    row = new float[cols];
    data=row;
}
//接下来进行二维数组的初始化
//此处省略若干代码

这种方式不可行的原因是,申请到的空间都是不连续的,可是Mat的初始化函数已经假定了第四个参数传来的数组空间是连续的。正是因为这个矛盾,导致使用第三种方式时,会报错,访问到无法访问的地址。

(方法三纠正)不过话说回来,如果是二维数组空间连续的话,还是可以通过这个二维数组进行Mat的初始化的(但是这样就不算是动态分配内存空间了,而是一开始就给定了固定大小的一块空间)。比如opencv的示例代码introduction_to_svm.cpp中:

// Set up training data
//! [setup1]
int labels[4] = {1, -1, -1, -1};
float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
//! [setup1]
//! [setup2]
Mat trainingDataMat(4, 2, CV_32FC1, trainingData);
Mat labelsMat(4, 1, CV_32SC1, labels);
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

OpenCV学习笔记(2):Mat矩阵的初始化

在研究Mat矩阵的初始化的时候,发现其不能像Matx轻量级矩阵那样,直接利用数组来进行初始化,而是利用一个内部的变量类型:Scalar来进行初始化的。参考手册中的构造函数如下所示: (1) Mat:...

opencv中Mat和数组赋值的几种方法

用opencv还不太熟练时,经常会在一些小地方出错,特别是Mat的赋值。现在总结一下我用到的几种方法。 Mat a = (Mat_(2,2)<<1,2,3,4); float b[4]={5,6,7...

opencv2 Mat分配的数据空间

这里先从Mat的几种初始化说起。 (1) Mat::Mat() (2) Mat::Mat(int rows, int cols, int type) (3) Mat::Mat(Size size, i...

OpenCV中Mat的C++用法介绍

Mat       OpenCV 自 2001 年出现以来。在那些日子里库是围绕C接口构建的。在那些日子里,他们使用名为IplImage C 的结构在内存中存储图像。这是您将在大多数较旧的教程和...

【VS开发】C++ opencv Mat基础

OpenCV2:Mat 1.Mat基础 在计算机内存中,数字图像是已矩阵的形式保存的。OpenCV2中,数据结构Mat是保存图像像素信息的矩阵,它主要包含两部分:矩阵头和一个指向像...

opencv Mat子矩阵赋值小tip

总所周知,Mat类型由头部和数据两个部分组成,从一个Mat中提取的子矩阵共享相同的储存空间。 基于以上知识,在进行Mat子矩阵赋值的时候,首先需要得到Mat的子矩阵。 这里设初始矩阵为A,子矩阵为...

OpenCv:Mat矩阵的初始化

在研究Mat矩阵的初始化的时候,发现其不能像Matx轻量级矩阵那样,直接利用数组来进行初始化,而是利用一个内部的变量类型:Scalar来进行初始化的。参考手册中的构造函数如下所示: (1) Ma...

初始化Mat的几种方法

1. 调用Mat的构造函数或者create函数,如:   // make a 7x7 complex matrix filled with 1+3j. Mat M(7,7,CV_32FC2,Sca...

OpenCV中矩阵类详解之一:Mat

Mat::eye 返回一个恒等指定大小和类型矩阵。 C++: static MatExpr Mat::eye(int rows, int cols, inttype) C++: static MatE...

Mat矩阵的初始化

在研究Mat矩阵的初始化的时候,发现其不能像Matx轻量级矩阵那样,直接利用数组来进行初始化,而是利用一个内部的变量类型:Scalar来进行初始化的。参考手册中的构造函数如下所示: (1) Ma...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)