6

私はプロジェクトの途中で、 ​​and を使用しようとしていmalloc()ますrealloc()。malloc すると機能することはわかっていますが、realloc を使用すると、割り当てられたメモリの量はまったく変わりません。realloc は、既に割り当てられているメモリを再割り当てします。

ここに私が持っているものがあります:

これには以下が含まれます。

#include <stdlib.h>

私は構造体を持っています:

struct student {
    int age;
    int numOfClasses;
    int gender; //0 male; 1 female
} student;

malloc を使用してこれらの構造体を 7 つ作成する場合は、次のコード行を使用します。

student stud* = (structure*) malloc(7*sizeof(student));

この行は機能します。そのコード行は構造体のサイズを取り、それを 7 倍します。要するに、これは 7 つの構造体の配列を作成するのに十分なメモリを取得します。

これを 8 に変更したい場合、Aは以前に割り当てられたメモリ、Bは新しい割り当てられた (または再割り当てされた) メモリです。

ここに画像の説明を入力

コードでの使用方法は次のとおりです。

stud = (student*)realloc(stud, 8*sizeof(student));

私の知る限り、realloc は 2 番目のパラメーターで変数を受け取り、その量のメモリを malloc します。次に、ポインター (または以前に malloc された) を取得し、malloc されたばかりのメモリに、指定されたポインターから可能な限り多くのデータを格納します。もちろん、2 番目のパラメーターは、以前に割り当てられたサイズよりも大きくなければなりません。そうしないとstud、最後にメモリがいくらか失われます。これが私の問題です。上記の行を呼び出しても、何も変わりません。mallocされた配列の長さはまだ7です。また、再割り当てするのに十分なメモリがあることも確信しています。

私はこれを正しく行っていますか?私の問題はどこにあるのでしょうか?

4

2 に答える 2

11

の動作に関するあなたの理解reallocはほぼ正しいです。別のポインターを返す必要はありません。最初のブロックの後に十分な未使用のメモリがあった可能性があるため、ヒープ マネージャーは同じポインターを返すことができます (ただし、ブロックが大きくなったことを認識できるように、ヒープ マネージャー自身の内部状態を調整します)。

ただし、1 つの小さな間違いを犯しました。

stud = (student*)realloc(stud, 8*sizeof(student));

studここでは、ポインターを からの戻り値に置き換えていますrealloc。メモリ不足が原因で戻っNULLてきた場合は、元のポインタが失われstud、メモリがリークされています。代わりに一時ポインタを使用する必要があります。

tmp = realloc(stud, 8*sizeof(student));
if (tmp)
    stud = tmp;

また、実際には 8 番目のスロットに何かを入れる必要があることに注意してください。再割り当て後、8 番目のスロットは有効に割り当てられたメモリですが、意味のあるものを格納するまでガベージが含まれています。

于 2013-03-08T13:03:45.140 に答える
4

これは機能するはずですが、次の推奨事項があります。

malloc からのリターンをキャストしないでください。Cでは役に立たず、含めるのを忘れたことを隠すかもしれません<stdlib.h>

ptr = realloc (ptr, ...)realloc が を返す場合にメモリ リークが発生するため、使用しないでくださいNULL。代わりに、

if ((new_ptr = realloc (stud, 8 * sizeof (*stud))) != NULL) {
     stud = new_ptr;
} else {
     scream_and_die("out of memory");
}

そして を使用しますsizeof (*stud)。つまり、指しているタイプではなく、ポインタを使用して式を参照します (割り当てたポインタの特定のタイプとは無関係にするため)。このように、typedef の名前を変更するときに、malloc/realloc 行を変更する必要はありません。つまり、C での動的メモリ割り当てのベスト プラクティスは、

#include <stdlib.h>
sometype *ptr;
...
ptr = malloc (N * sizeof *ptr);

N sometypes の配列の場合。

于 2013-03-08T13:08:30.000 に答える