2013-05-06 91 views
0

我試圖聲明一個指向二維浮點矩陣的指針,以便獲得我的圖像數據的動態行爲,但是Im有一個編譯錯誤C2057:預期的常量表達式。我認爲一個指針必須以這種方式鑄造,但顯然不是。請任何人都可以幫助我?謝謝!!如何聲明一個指向2d浮點矩陣的指針?

//Image size input 

int imheight; 
int imwidth; 

cout << "Please, enter image height: \n>"; 
scanf ("%d",&imheight); 
cout << "Please, enter image width: \n>"; 
scanf ("%d",&imheight); 

const int imheight2 = imheight; 
const int imwidth2 = imwidth; 

float *zArray[imheight2][imwidth2]; 

這是我的其他功能之一,我試圖hace訪問zArray。我不是獲取數據正確讀出:

void LoadRIS(char* inputFileName , float** zArray, int imageHeight , int imageWidth){ 

    // Load input RIS file 
FILE* lRis = fopen (inputFileName, "rb"); 

// Jump to data position 
for (int i = 0; i < 88; i++){  
    uchar a = getc (lRis); 
} 

// Read z array 
size_t counter = fread (*zArray , 1 , imageHeight * imageWidth * sizeof(zArray) , lRis); 

//Get max value of RIS 
float RISmax = zArray [0][0]; 
float RISmin = zArray [0][0]; 
for (int i=0; i<imageHeight; i++) 
{ 
    for (int j=0; j<imageWidth; j++) 
     { 
      if (zArray[i][j] > RISmax) 
      RISmax = zArray [i][j]; 
      if (zArray[i][j] < RISmin) 
      RISmin = zArray [i][j]; 
     } 
} 
std::cout<<"The max value of the RIS file is: "<<RISmax<<"\n"; 
std::cout<<"The min value of the RIS file is: "<<RISmin<<"\n"; 
Beep(0,5000); 


// Close input file 
fclose (lRis); 

}

+0

除了回答說些什麼,該類型是指針的二維數組,而不是一個指向二維數組的指針。你會想'float(* zArray)[imheight2] [imwidth2];'。 – 2013-05-06 10:11:24

+0

這個問題被標記爲C和C++,但答案是不同的。 C支持可變長度數組已經有一段時間了,所以小的可變長度數組可以並且應該用'float foo [r] [c];'定義。其中一個標籤應該被刪除。 – 2013-05-06 11:43:37

回答

0

嘗試此(動態分配)

//Image size input 

int imheight; 
int imwidth; 

cout << "Please, enter image height: \n>"; 
scanf ("%d",&imheight); 
cout << "Please, enter image width: \n>"; 
scanf ("%d",&imwidth); 

float** zArray = new float*[imheight]; 
for(int i=0;i<imheight;i++){ 
    zArray[i] = new float[imwidth]; 
} 

當然,你需要釋放分配:

for(int i=0;i<imheight;i++){ 
    delete[] zArray[i]; 
} 
delete[] zArray; 

希望這有助於:)

附:正如@FrankH所說,這稱爲太多new s和delete s,浪費了很多時間。更好的想法應該是一起分配imwidth * imheight空間。

+0

工作很好,謝謝!順便說一下,我如何從另一個函數訪問雙指針float **的值?它崩潰了 – Nicolai 2013-05-07 08:54:44

+0

@Nicolai你的意思是訪問2d數組中的值?只需使用zArray [i] [j]即可。我想知道整個代碼,你能編輯這個問題並粘貼你的'另一個函數'代碼嗎? – hongtao 2013-05-07 09:54:17

+0

嗨洪濤,只是在問題中貼了一個函數。我現在沒有崩潰,但我無法正確讀取文件並將其加載到我的zArray – Nicolai 2013-05-07 11:08:23

2
const int imheight2 = imheight; 
const int imwidth2 = imwidth; 

它不會使常量表達式。你不能用這樣的邊界創建數組。您應該使用dynamic-allocationvector

2

問題是您聲明瞭2 const int變量,但您並未指定它們的const值。 imheightimwidth不是恆定的。

如果你罰款STL:

std::vector<std::valarray<float> > floatMatrix; 

編輯:只是爲了您的信息,我在上面的代碼行放在>之間的空間沒有任何與我的編碼風格。您的編譯器可能會假設>>是正確的移位運算符而不是2個模板參數列表結束符。 Angew的評論總結如下。

+1

「>>」的「舊」解釋不是一個錯誤,C++ 03是這樣定義的(儘管許多編譯器支持將'>>'作爲擴展名)。第一個C++ 11使得這個解析是合法的,所以現在編譯器必須在適用時將'>>'理解爲模板終結符。 – Angew 2013-05-06 10:18:33

+1

看到它應該是一個矩陣,我會考慮'std :: valarray'而不是'std :: vector'。 – Angew 2013-05-06 10:19:49

+0

我想我可以將最後一條語句改寫爲更一般,這樣我就可以避免誤報任何人 – 2013-05-06 10:20:40

0

您不能使用具有動態大小的數組(您的寬度和高度變量不是編譯時間常量)。

您可以使用malloc()或new運算符以動態方式分配內存。

+0

你說得對,但我認爲Nicolai很可能使用C++,因爲變長數組不會導致C中的編譯器錯誤C2057。因此,這個問題的答案是正確的。 – Pixelchemist 2013-05-06 12:17:53

+0

那cplusplus。com引用是不好的...即使代碼示例是buggy('FreeDynamicArray'泄漏'(nRows-1)* nCols'單元的'T')。在C/C++中使用'dynamic multidimensional arrays'是不對的。堅持'std :: vector'和/或使用/實現一個合適的'matrix'類 - 用'operator(int,int)'而不是'[] []'。 – 2013-05-08 00:03:05

+0

你的網站確實是對的。我會刪除鏈接,因爲此功能可能會讓人們感到困惑。但是:由於我們得到了STL,所以沒有人應該瞭解如何使用動態內存? :X每個人都使用C++(特別是在使用C時)當然應該知道如何處理一維或多維數組!即使你(盡力)避免在你自己的代碼中使用它,你遲早會被要求知道這些東西。 – Pixelchemist 2013-05-08 09:26:46

-1

float *pMatrix = new float[imheight2*imwidth2];

這樣

float f = pMatrix[x*y];

+1

我想你的意思是'y * width + x' – 2013-05-06 10:29:15

2

代替float *zArray[imheight2][imwidth2]; 然後訪問元素應該是:

float **zArray = new float*[imheight2]; 

for(int i=0; i<imheight2; i++) 
{ 
    zArray[i] = new float[imwidth2]; 
} 
1

如果要做到這一點,那麼至少爲它編寫代碼:

float **zArray = new float*[imheight]; 
float *tmp = new float[imheight*imwidth]; 

for(int i=0; i<imheight; i++, tmp += imwidth) 
    zArray[i] = tmp; 

... 
delete[] *zArray; 
delete[] zArray; 

這至少避免了做兩個以上的new/delete[]電話。並且它保留了fread(*zArray, ...)的功能,如果內存不是連續的,那麼會中斷(如果通過多個new調用初始化它,通常不會發生)。

一個適當的包裝類會做一個new/malloc,如:

template <class T> class Array2D { 
private: 
    size_t m_x; 
    T* val; 
public: 
    Array2D(size_t x, size_t y) : 
     m_x(x)), 
     val(new T[x*y]) {} 
    ~Array2D() { delete[] val; } 
    T* operator[](size_t y) { return val + y*m_x; } 
} 

你還是這樣的實例不能分配給float**。它仍然在堆上分配,普通的常量維數組可以放在堆棧上。 float**的額外分配的唯一優點是您不必使用乘法操作 - 而是使用單獨的內存訪問;該類型的行爲可以被模板化/引入包裝類。

一般地,我更想要的multidimensional arrays are evil側面(另見https://stackoverflow.com/a/14276070/512360,或C++ FAQ, 16.16),但口味也不盡相同......