2011-01-23 18 views
4

私は関数内で配列のサイズを動的に探したいので、sizeof演算子を使用しました。しかし、私は予期せぬ結果を得ました。 ここには、私がしたいことを示す1つのデモプログラムがあります。sizeof演算子の問題

//------------------------------------------------------------------------------------------ 
#include <iostream> 

void getSize(int *S1){ 

    int S_size = sizeof S1/sizeof(int); 
    std::cout<<"array size(in function):"<<S_size<<std::endl; 
} 

int main(){ 

    int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6}; 
    getSize(S); 
    std::cout<<"array size:"<<sizeof S/sizeof(int)<<std::endl; 
    return 0; 
} 
//------------------------------------------------------------------------------------------ 

コンパイルコマンド:G ++ demo1.cc -o DEMO1 {Fedoraの12}

出力:

array size(in function):2 
array size:19 

なぜこれが起こっている、説明してください。 この問題を解決するには何ができるのですか?

+1

[this](http://stackoverflow.com/questions/1975128/sizeof-an-array-in-the-c-programming-language/1975133#1975133)回答と[this](http://質問.2384107/magic-arguments-in-function-templates)質問。 –

+2

配列がポインタでない理由の良い例です。テンプレートの – Oystein

答えて

9
void getSize(int *S1) 

あなたはこの関数に配列を渡すと、それはとてもsizeofオペレータは、ポインタのサイズを返します、ポインタ型に減衰します。

しかし、あなたは、あなたが関数内で、配列のサイズを持つことができます

template<int N> 
void getSize(int (&S1)[N]) 
{ 
    //N is the size of array 
    int S_size1 = N; 
    int S_size2 = sizeof(S1)/sizeof(int); //would be equal to N!! 
    std::cout<<"array size(in function):"<<S_size1<<std::endl; 
    std::cout<<"array size(in function):"<<S_size2<<std::endl; 
} 

int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6}; 
getSize(S); //same as before 

、としてあなたの関数を定義します! (おそらく64ビットOSを実行しているので)、あなたは8バイトであるポインタのサイズを、取得しているgetSize()インサイドhttp://www.ideone.com/iGXNU

+3

+1 – Marlon

+1

ありがとう..完璧に働いています。 –

0

あなたは配列へのポインタのサイズを取得しています。配列のサイズが必要な場合は、要素の数に各要素のサイズを掛けなければなりません。

3

はデモここに自分自身を参照してください。 main()では、配列のサイズを取得しています。

アレイサイズを知りたい場合は、getSize()の追加引数としてsizeof(S)の結果を渡します。

Nawazが提案したように、いくつかのコンテナ(std::vectorなど)や関数をテンプレート関数に変換する方法がさらにあります。

+0

実際には、getSize()が1つの引数しか取ることができない競技用の関数をコーディングする必要があります。提案ありがとう。:) –

0

配列のサイズを関数に渡す必要があります。

配列の最初の要素にポインタを渡すだけなので、関数には実際のサイズに関する情報はありません。 Dに

0

Sint *、あなたのマシンの2倍のサイズであるメモリアドレス、ある整数へのポインタです:あなたが考えてみれば

void getSize(int *S1, size_t size) 
{ 
    int S_Size = sizeof(*S1) * size; 
} 

これは、しかし冗長です整数。

配列のサイズ(つまり要素数)が必要な場合は、純粋なC言語で直接取得することはできませんが、これはC++の質問であるため、方法があります:vectorを使用します。方法はsize()です。

実は、これはかなり真実ではありません:あなたはSを宣言(そして、あなたの例ではそうであるように、それが明示的にコンパイル時に初期化されます場合にのみ - でもnew int[19]は動作しません)機能内sizeofthese docsを参照)

int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6}; 
vector<int> v(S, S + sizeof(S)/sizeof(int)); 

、その後、あなたがv.size()を使用することができます。オペレータは、実際にはC++は、あなたがこれを行うことができます理由は正しい答えを、取得しています。

ナワズにより、テンプレートのバージョンは、他の場所の周りにC++の配列の構築に関する完全な情報を運ぶにコンパイラに強制的に別の優れた提案です(再び、これはすべて、なぜあなたをしている、時間をコンパイルで知られていることに注意してください引数のサイズを明示することができます)。 sizeofの偶然の誤用、このタイプのを防ぐために

0

、あなただけの配列上で動作関数を定義することができます

template<class T, int N> 
int array_size(T (&)[N]) { 
    return N; 
} 

あなたのコードでこれを使用する場合に適用されたとき、あなたはコンパイラエラーが表示されますS1であり、配列ではないからです。さらに、sizeof array/sizeof array [0]よりも短く明示的です(最初の項目のサイズを使用すると、配列タイプを繰り返す必要はありません)。

これは既にBoostではより一般的な形式(std :: vectorなどのサイズメソッドで何かを受け入れる)で存在します。

関連する問題