1. 程式人生 > >C++ 動態分配陣列空間,以及opencv中Mat類的初始化

C++ 動態分配陣列空間,以及opencv中Mat類的初始化

在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; }

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);

相關推薦

C++ 動態分配陣列空間以及opencvMat初始

在C++中,如果想要申請動態陣列,必須要用動態分配的方式。 int **matrix=new int*[num_of_rows]; for(int i=0;i<num_of_rows;i++){ int *row=new int[num_of

C++動態分配記憶體空間 : new 和 delete

1.什麼是new和delete 在C語言中我們可以利用標準庫函式中的 malloc 和 free 來動態分配記憶體空間,而在C++中提供了運算子 new 和 delete 來取代 malloc 和 f

引用父的靜態欄位不會導致子初始

先看程式碼 // 父類 public class SuperClass { static { System.out.println("SuperClass Init!"); } public static int valu

OpenCVMatat函式具體用法

Mat.at<儲存型別名稱>(行,列)[通道] 具體例子 假設M中儲存一張512*512的彩色圖片,那這張圖有三個通道,下面兩個at都表示的是這個矩陣的最右下的那個點。 M矩陣有512行,512*3列,不加入通道引數,也就是第一個at命令,是簡單的遍歷,可以

OpenCVMat的影象如何設定ROI

Mat類表示的影象進行ROI操作有兩種方法 (1)使用拷貝建構函式Mat(constMat& m, const Rect& roi ),矩形roi指定了興趣區 例如: Mat src = imread(“xx.jpg”); Mat srcROI( src,

c++動態分配空間建立三維陣列

#include<iostream> using namespace std; int main(){ int (*cp)[9][8] = new int [7][9][8];//建立一個動態的三維陣列 for (int i = 0;i<

C語言動態庫建立方法以及和python混合程式設計

這篇小結是2016年暑假在新疆出差階段所寫,因為專案需要所以研究了一下。 如有錯誤,歡迎互相交流。 不同編譯器實現python呼叫C語言動態庫方法小結 Windows平臺下Visual Studio 2010編譯器建立動態庫,並呼叫 第一步:建立動態dll動態庫

C語言--動態分配記憶體空間的使用方法

#include <stdio.h> #include <stdlib.h> int main() { int i; int *nums; //為指標分配動態的記憶體空間 // nums = (int *)mall

c++動態分配二維/三維陣列的記憶體

轉自http://blog.csdn.net/boylinux/article/details/7783871 本文主要目的是用c和c++分別實現動態分配二、三維陣列。一般而言,在C中用malloc和free實現,而在C++中用new和delete。 new和delete是

malloc動態分配陣列以及指標陣列大小

對於二維陣列:一般來說,當給兩個數分別表示行列,但兩個數的範圍過大,就需要動態分配。 int i,j,m,n; scanf("%d%d",&m,&n); int **a;

C語言動態分配陣列

摘要的重要性是不言而喻的,每次發文章我都很糾結如何寫出一個有特色的摘要來,能夠以最為簡短的文字向讀者描述出我所要表達的東西。但是常常出現的問題是,摘要寫得太簡短了,讀者看了不清楚文章究竟要講啥;摘要寫得稍微長點的話自然能夠描述清楚所要表達的東西,但是卻也出現了另外一個問題,

c++動態分配二維陣列

程式碼 #include <iostream> using namespace std; typedef int Type; Type** create(int row, int col)

C++ Code:動態分配陣列記憶體的六種方法

問題:         如何快速給陣列分配自定義長度的記憶體,方法有哪些?         本部落格提供六種方法介紹,包含各種常用用法,且程式碼片親自 編寫-註解-編譯-通過,對讀者負責。 闡述:         提到動態分配C++的陣列,我們想到的標籤會有:malloc-

C語言動態分配陣列指標的釋放問題

我們都知道要實現根據程式的需要動態分配儲存空間,在C中需要使用到stdlib.h中的兩個函式,malloc,free,兩個函式的介紹如下: malloc函式的原型為: void *malloc (u igned int size) 其作用是在記憶體的動態儲存區中分配一個長

asa 動態地址的轉化以及端口映射

acl mic ftp服務 內網 cati size object mage 昨天 asa 動態地址的轉化,以及端口的映射實驗拓撲圖 4. 實驗目的 : 1. 將內網 10.1.1.0 ,10.2.2.0 網段 通過pat轉換 能夠訪問外網 ftp服務器

C 動態分配內存

動態內存 clu all ... 內存 num 首地址 sizeof 動態分配內存 動態內存分配主要的函數有: malloc(), realloc(), calloc() 都包含在頭文件 #include <stdlib.h> 裏 這幾個函數的定義: void

[C++] STL庫函式之字串string::npos的介紹以及string的find函式~

npos經常和find一起用~它們兩個都在標頭檔案<string>裡面~先看用法: #include <iostream> #include <string> us

linux redhat 安裝gcc gcc-c++和下載到本地以及可能出現的問題

一、直接安裝並更新版本: #yum install gcc #yum install gcc-c++ 檢視版本: #gcc --version #g++ --version 二、下載到本地,手動安裝rpm: 1、

c/c++ 動態申請陣列

new和delete運算子用於動態分配和撤銷記憶體的運算子 new用法:           1.     開闢單變數地址空間                1)new int;  //開闢一個存放陣列的儲存空間,返回一個指向該儲存空間的地址.int *a = new int 即為將一個int型別的地址賦值

c++ 建立有序單鏈表以及兩個有序單鏈表合併

首先是Node結點的建立 //建立結點 class Node { public: Node(){ next=NULL;data=0; } Node(int n){ next=NULL;da