7

固定サイズ 20 で既に malloc されている構造体に、さらに 10 個の要素を追加しようとしています。これが、構造体を定義する方法です。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct st_temp {
   char *prod;
};

int main ()
{
   struct st_temp **temp_struct;

   size_t j;
   temp_struct = malloc (sizeof *temp_struct * 20);
   for (j = 0; j < 20; j++) {
      temp_struct[j] = malloc (sizeof *temp_struct[j]);
      temp_struct[j]->prod = "foo";
   }

   return 0;
}

だから私が念頭に置いていたのは、次のように再割り当てすることでした(ただし、方法はわかりません):

temp_struct = (struct st_temp **) realloc (st_temp, 10 * sizeof(struct st_temp*));

余分な10個の要素を追加し、

   for (j = 0; j < 10; j++)
      temp_struct[j]->prod = "some extra values";

どうすればこれを達成できますか?どんな助けでも大歓迎です!

4

2 に答える 2

9

を使用する場合、追加するバイト数ではなく、新しいサイズを指定realloc()する必要があります。そう:

temp_struct = (struct st_temp **) realloc (temp_struct, 30 * sizeof(struct st_temp*));

30 はもちろん、元の 20 にさらに 10 を加えたものです。このrealloc()関数は、メモリ ブロックを移動する必要がある場合、元のデータを新しい場所にコピーします。

次に、余分な 10 個の要素を追加すると、次のようになります (0 ではなくインデックス 20 から開始)。

for (j = 20; j < 30; j++) {
    temp_struct[j]->prod = "some extra values"; 
}
于 2010-10-31T21:33:00.483 に答える
7

メモリ リークを回避するには、再割り当てを慎重に処理する必要があります (詳細は後述)。再割り当て機能:

void *realloc(void *ptr, size_t size)、 どこ

ptrmalloc= 元の ( 'ed) メモリ ブロックへのポインタ、および

size= メモリ ブロックの新しいサイズ (バイト単位)。

realloc動的に割り当てられたメモリ ブロックの新しい場所 (変更されている可能性があります) を返します。再割り当てに失敗した場合は NULL を返します。NULL を返す場合、元のメモリは変更されないため、 の戻り値には常に一時変数を使用する必要がありますrealloc

例でこれを少し明確にします (興味深い点: realloc 構文は malloc の構文と似ています (余分なキャストなどは必要ありません)。また、realloc の後、malloc の後で行ったのと同じ手順を新しいオブジェクトに対して生成する必要があります):

struct st_temp **temp_struct;
temp_struct = malloc(20 * sizeof *temp_struct);
if (temp_struct == NULL) { /* handle failed malloc */ }
for (int i = 0; i < 20; ++i) {
    temp_struct[i] = malloc(sizeof *temp_struct[i]);
    temp_struct[i]->prod = "foo";
}

// We need more space ... remember to use a temporary variable
struct st_temp **tmp;
tmp = realloc(temp_struct, 30 * sizeof *temp_struct);
if (tmp == NULL) { 
    // handle failed realloc, temp_struct is unchanged
} else {
    // everything went ok, update the original pointer (temp_struct)
    temp_struct = tmp; 
}
for (int i = 20; i < 30; ++i) { // notice the indexing, [20..30)
    // NOTICE: the realloc allocated more space for pointers
    // we still need to allocate space for each new object
    temp_struct[i] = malloc(sizeof *temp_struct[i]);
    temp_struct[i]->prod = "bar";
}
// temp_struct now "holds" 30 temp_struct objects
// ...
// and always do remember, in the end
for (int i = 0; i < 30; ++i)
    free(temp_struct[i]);
free(temp_struct);

これは実際には構造体の配列ではなく、構造体へのポインターの配列であることに注意してください。必要に応じて、構造体の配列の配列でさえあります。最後のケースでは、各サブ配列の長さは 1 になります (1 つの構造体にしかスペースを割り当てないため)。

于 2010-10-31T21:43:10.837 に答える