2012-10-07 62 views
1

我用一個模板定義了一個類,該模板定義了一個通用數組類型T個元素N.我有另一個有這個數組實例作爲成員的類。當我嘗試使用setString函數時,我傳遞的數組從任意的15個元素到4個元素。作爲參數傳遞給C++類時的內存丟失

// testClassArraySize.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include <stdio.h> 
#include <iostream> 
#include <istream> 
#include <ostream> 
using namespace std; 

template<class T, int N> 
class CArray { 
public: 
    T arr[N]; 
    CArray(void) {/*arr=(T *)malloc(sizeof(T)*N);*/ 
     if (arr == NULL) { 
      cout << "allocation error\n"; 
     } 
    } 
    ; 
    //CArray (int n) {arr=new T [n]; if(arr==NULL){exit(0); cout<<"allocation error\n";}}; 
    CArray operator=(const T *); 
    T operator[](const int i) { 
     return arr[i]; 
    } 
    ; 
}; 

template<class T, int N> 
CArray<T, N> CArray<T, N>::operator=(const T *srce) { 
    size_t x = sizeof(arr); 
    size_t y = sizeof(srce); 
    for (int j = 0; j < sizeof(arr); j++) { 
     if (j > sizeof(srce)) { 
      arr[j] = 0; 
      break; 
     } 
     arr[j] = srce[j]; 
    } 
    return *this; 
} 

class myTestClass { 
private: 
    CArray<char, 15> myString; 
public: 
    myTestClass setString(char set[15]) { 
     myString = set; 
     size_t x = sizeof(set); 
     return *this; 
    } 
    ; 
}; 

int main() { 
    myTestClass myObject; 
    myObject.setString("helloWorld"); 
    return 0; 
} 

有沒有人有任何想法爲什麼?

+1

當然,您還沒有啓用任何編譯器警告,是嗎?這些可以非常有幫助。 –

+0

爲這個想法+1,但MSVC10沒有任何。你期望哪一個? – dyp

回答

2

這有幾個問題,但一個你可能會看到的是線

CArray<T, N> CArray<T, N>::operator= (const T *srce) 

注:const T* source是一個指針,因此sizeof(srce)是指針的大小。我猜你正在使用32位系統?

sizeof爲您提供了對象的大小(即「存儲區域」)。對於數組,這是整個數組的大小(以字節爲單位)。 sizeof(int[10]) == sizeof(int) * 10。指針本身就是一個對象,其大小取決於C++實現(OS,編譯器等)。在32位系統上,它通常是4個字節。因此sizeof(char*)是4字節,則傳遞給函數數組的不是長度,也就是仍然sizeof((char*)(char[10]))是4字節,而不是10

可能看到的另一個問題(而是僅由調試/跟蹤)是setString(char set[15])是解決爲setString(char* set)。因此x = sizeof(set)解析爲x = sizeof(char*)其通常4.

傳遞「HelloWorld」的到setString,它期待一個 15項字符數組 char*;我會說這不是一個好主意,因爲「helloWorld」的類型爲char const[10](請注意const)。 採用15個字符數組的正確語法是char (&set)[15]

如果添加像一個模板成員函數可以做到這一點更優雅:

// in class CArray 
template < std::size_t length > 
CArray& operator= (const T (&srce)[length]); // note I return a reference, so no copying 

這樣一來,你會得到數組的大小作爲一個模板參數。注意:因爲我在作業中使用了const T,所以還需要在setString中強制執行const。

template < class T, int N > 
template < std::size_t srce_length > 
CArray < T, N >& CArray < T, N > :: operator= (const T (&srce)[srce_length]) 
{ 
    for (int j = 0; j < N; j++) { // N is the own length 
     if (j >= srce_length) { // note the >= instead of >, and srce_length instead of sizeof 
      arr[j] = 0; 
      break; 
     } 
     arr[j] = srce[j]; 
    } 
    return *this; 
} 
+0

謝謝。但是當我將數組傳遞給setString時,甚至在我調用CArray operator =(const T * srce)之前,內存仍然丟失......但是,請嘗試此解決方案。 – bathtub

+0

正如我所提到的,嘗試將'setString'的簽名更改爲'char const(&set)[15]'。 – dyp

+0

好的,謝謝。這有助於。我不明白是什麼把地址運算符作爲參數或返回值不過。 – bathtub

相關問題