1

私はこのような質問に対する他の答えを見たことがありますが、どれも私にとってはうまくいかないようでした。動的配列があるとしましょう:

int* myarray;
myarray = malloc(myarray, 4*sizeof(int));
myarray[0] = 1;
myarray[1] = 2;
myarray[2] = 3;
myarray[3] = 4;

私がやりたいのは、配列の最初の要素を削除することです(そして、配列はどんどん大きくなっていくので、解放します) 。縮小すると、配列の最後のrealloc要素が削除されることをよく知っています。これについて何かアイデアはありますか?これは可能ですか?

前もって感謝します!

4

4 に答える 4

6

私が考えることができる1つの方法は、


memmove(myarray, myarray+1, 3*sizeof(int))

次にrealloc、配列を縮小するために使用します。Cでこれを行うより効率的な方法があるかどうかはわかりません。

于 2013-01-30T03:22:40.187 に答える
0

Cでそれを行うための適切でクリーンな方法が見つかるとは思いません。C++はそれを行う一部の言語であり、ほとんどすべてのOO指向言語はそれを行うことができますが、Cはできません。私が考えることができるのはメモリを移動し、はい、reallocを呼び出すか、メモリの再利用ポリシーで空と見なされる既知の値に解放する位置を設定します。

問題を解決するもう1つの方法は、アレイを動的に実装することです。そこに行きたいかどうかはわかりませんが、行きたい場合は、簡単な例を次に示します。

整数のみを保存しているので、次のような構造体:

typedef struct DynamicArray_st{
 int x;
 struct DynamicArray_st *next;
}DynamicArray;

プログラムが必要とする要素の割り当てと解放を可能にします。また、途中、開始、または終了に挿入することもでき、同じように無料で挿入できます。

これを行う方法は、この動的型の先頭へのポインターを保存してから、それを反復処理することです。問題は、[]表記ではデータにアクセスできないことです。反復が必要であり、処理時間が重くなります。

それ以外に、コードは次のようになります。

DynamicArray *array = malloc(sizeof(DynamicArray)); /*Just a first element that will stay empty so your Dynamic array persists*/
 array->next = NULL;
 DynamicArray *aux = array;
 DynamicArray *new;
 for(i = 0; i<4; i++){
    new = malloc(sizeof(DynamicArray));
    new->next = NULL;
    new->x = i+1;
    aux->next = new;
    aux = new;
 }

ここでは、各構造体が次の構造体を指し、内部に整数を持つように、構造体のシーケンスがあります。今ならあなたは次のようなことをするでしょう:

aux = array->next; /*array points to that empty one, must be the next*/
 while(aux != NULL){
   printf("%d\n",aux->x);
   aux = aux->next;
 }

次の出力が得られます。

1
2
3
4

そして、最初の要素を解放するのは次のように簡単です。

  aux = array->next;
  array->next = aux->next;
  free(aux);

それを描画しようとすると(構造体はボックスで、next / aux / nextは矢印です)、1つのボックスの矢印がボックスの輪郭を示します-解放したいボックスです。

お役に立てれば。

于 2013-01-30T03:49:11.240 に答える
0

通常、アレイに対して「削除」操作を実行することはできません。おそらく、リンクされたリストを作成して使用したいですか?

C++には、std::vectorこれをサポートするものがあります。それが行うことは、後で来る要素を1要素だけ前方にシフトすることです。これを実装して、後で呼び出すことができますrealloc

最初の要素だけを削除する必要がある場合、それらを逆に保存することは明らかな回避策です。

于 2013-01-30T03:22:11.213 に答える
0

他のすべての要素を 1 つに沿ってシャントする必要があります。概念的には、次のようになります。

for( int i = 0; i < 3; i++ ) p[i] = p[i+1];

他の人が述べたようにmemmove、上記のループを使用するのではなく、オーバーラップするメモリ セグメントをシフトするために最適化されています。

配列が大きくなると、データの移動は依然として非効率的です。アイテムを追加するたびに配列を再割り当てするのはさらに悪いことです。一般的なアドバイスは、それをしないことです。配列の大きさと、現在そこに格納されているアイテムの数を追跡するだけです。大きくするときは、かなり大きくします (通常はサイズを 2 倍にします)。

配列を事前に割り当てる循環キューが必要なように思えますが、アイテムをプッシュおよびポップすると、ヘッドポインターとテールポインターがお互いをぐるぐる追いかけます。

于 2013-01-30T03:23:36.093 に答える