2009-04-07 8 views
3

は、私は次の宣言でヘッダーを与えられている:この宣言はどのように変更する必要がありますか?

//The index of 1 is used to make sure this is an array. 
MyObject objs[1]; 

しかし、私はこの配列を動的にプログラムが開始されたものをサイズのようにする必要があります。私はMyObject * objsとして宣言すればよいと思うだろうが、元のプログラマーがこのように宣言していれば何らかの理由があると考えられる。

は、私はこれを動的にサイズを変更することができますとにかくありますか?または私はそれをポインタに変更してからmalloc()する必要がありますか?

私はいくつかは、これを行うために何とか新しいキーワードを使用してもらえますか?

答えて

6

あなたは正しいです。そのサイズを動的にインスタンス化する場合は、ポインタを使用する必要があります。

(?あなたがC++を使っているので、代わりにmalloc関数新しい演算子を使用しない理由)

MyObject* objs = new MyObject[size]; 
+0

これは、MyObject * objs = new MyObject [size];である必要があります。右? – Tjofras

+0

ああ、あなたは正しいと思います。私はC#に慣れてきたので、私のC++を汚しています:) –

16

使用STL vectorは:

#include <vector> 

std::vector<MyObject> objs(size); 

ベクターは、dynamic arrayStandard Template Libraryの一部です。それはあなたのように自動的に配列にpush backオブジェクトのサイズを変更し、[] operatorの通常Cアレイのようにアクセスすることができます。 listとは異なり - - また、&objs[0]は、メモリ内の連続配列を指すように保証された容器が空でない場合。あなたが動的にサイズの配列をしたい場合はSTLを使用して

+0

"&objs [0]はメモリ内の連続したシーケンスを指し示すことが保証されています"しかし、あなたのベクトルが空ではないことを確かめるときにのみOKです。それ以外の場合は、未定義の動作につながる可能性があります。 –

+0

それは本当であり注目されています。 –

+0

事前にサイズを知っていれば、Vector :: reserve()が役立ちます。 –

0

は、一つはstd::vectorあり、いくつかのオプションがあり、最高です。挿入するのに気にかけなければ、std :: listを使うこともできます。

+0

それは彼の問題を解決しません。ポインタに変更することができれば、サイズを変更するためのたくさんのオプションがあります。 reallocは、現在の宣言を使用している間、配列のサイズを変更させません。 – jalf

0

ITSは思わ - はい、この変更を行うことができます。
しかしsizeof(objs)のコードを確認してください。

MyObj *arr1 = new MyObj[1]; 
MyObj arr2[1]; 

sizeof(arr1) != sizeof(arr2) 

多分、この事実はコードのどこかで使用されています。

3

ポインタを に変更してからmalloc()するだけですか?

これを行うと、mallocのメモリにあるオブジェクトのコンストラクタはどのように呼び出されますか?私はあなたにヒントを与えます - 彼らはそうではありません - あなたはstd :: vectorを使う必要があります。

0

このコメントは非常に悪いです。 1つの要素の配列は、たとえコメントがそうではないとしても、配列です。

私は誰もこのように "配列です"を強制しようとしたことはありません。配列の構文は大部分が構文的な糖である(a[2]2[a]と同じ結果を返します。すなわち、第3要素はathis is an interesting and valid syntax but usually a very bad form to use)です。なぜなら、プログラマーを何の理由もなく混乱させるからです)。

配列の構文は主に構文上の砂糖なので、ポインタへの切り替えも意味があります。しかし、あなたがそれを行うつもりならば、new[]を使って行くことは意味があります(コンストラクタが無料で呼び出されるため)std::vectorで行くことはもっと意味があります(あなたは毎晩delete[]と覚えておく必要がないので戻り値、ブレーク、ステートメントの終了、例外のスローなどの理由で配列が範囲外になります)。

1

私は構造体または共用体内のポインタとして使用される配列しか見ていません。これは古くからあり、lenと文字列の最初の文字をハッシュとして扱い、スクリプト言語の文字列比較の速度を向上させました。

コードはこれに類似していた:

union small_string { 
    struct { 
     char len; 
     char buff[1]; 
    }; 
    short hash; 
}; 

その後、mallocを使用して初期化されたsmall_string、Cのキャストが効果的にreinterpret_castは

small_string str = (small_string) malloc(len + 1); 
strcpy(str.buff, val); 

であることに注意と平等をテストするために

int fast_str_equal(small_string str1, small_string str2) 
{ 
    if (str1.hash == str2.hash) 
     return strcmp(str1.buff, str2.buff) == 0; 
    return 0; 
} 

ご覧のとおり、これは移植性が高く、安全なC++スタイルではありません。しかし、ほとんどのスクリプト言語の基礎となる短い文字列で索引付けされた連想配列のスピードを大幅に改善しました。

私はおそらくこのスタイルのC++を避けるでしょう。

1

これはどこかで構造体の最後にありますか?私が見てきた

1つのトリックはarrは、可変サイズの配列となるように、構造体にsizeof (struct foo)より

struct foo { 
/* optional stuff here */ 
int arr[1]; 
} 

とのmallocより多くのメモリを宣言することです。

これは、可変サイズの配列が利用できなかったので、私がCをハッキングしていたときのCプログラムでかなり一般的に使用されていました。

ほとんどの場合、正しい方法は配列をSTLベクトルに変更することです。

関連する問題