ポインタのコツを少しずつ掴んでいます。しかし、まだいくつか疑問があります。
ポインターが指している実際の位置をシフトしているため、ポインター演算を使用するとメモリリークが発生する可能性はありますか?
つまり、文字列 char を char ごとにコピーするために上向きにカウントするとしたら、ポインターがどこを指していたかを C が「知る」ためにカウントダウンする必要があるでしょうか?
ありがとうフランク
ポインタのコツを少しずつ掴んでいます。しかし、まだいくつか疑問があります。
ポインターが指している実際の位置をシフトしているため、ポインター演算を使用するとメモリリークが発生する可能性はありますか?
つまり、文字列 char を char ごとにコピーするために上向きにカウントするとしたら、ポインターがどこを指していたかを C が「知る」ためにカウントダウンする必要があるでしょうか?
ありがとうフランク
malloc()
または同様の関数を使用し、必要なときに呼び出さない場合、メモリリークが発生する可能性がありfree()
ます。free()
は常に、によって返されるポインタを使用して呼び出す必要があるmalloc()
ため、次のようなことを行う場合はそうです。
int* ptr = malloc(sizeof(int));
free(ptr + 1);
未定義の動作を引き起こします。メモリリーク、セグメンテーション違反など、何でも可能です。
メモリはヒープに割り当てられます。ポインタは、メモリ内の場所へのポインタです。後で解放するには、割り当てられたメモリの開始アドレスを知る必要があります。
これは、割り当てられたメモリに関する情報 (割り当てられた量など) をメモリ管理システムが記憶する必要があるためです。これにより、メモリ管理システムは後で解放する量を認識し、同じブロックが別の malloc 呼び出しに割り当てられないようにすることができます。メモリの開始アドレスは、それを識別するものです。
ポインターをいじりたい場合は、そのコピーを取り、元のポインターを変更しないでください。
int *x = malloc(...);
int *y = x;
... pointer arithmetic with y
free(x);
メモリリークは、動的メモリ割り当てで発生します。割り当てたヒープセグメントへのポインタを格納してから、そのポインタ参照を変更すると、以前に割り当てられたメモリを解放できない可能性があります。
別のポインタを使用し、割り当てられたメモリへの初期参照を保持する必要があります。例えば:
char *pointer = (char*)malloc (SIZE); /*alloc space for storing a string of size SIZE*/
char *pointer2 = pointer;
int i;
for (i = 0 ; i < SIZE ; i++){
pointer2 += 1;
//you are modifying the second pointer so you always keep a reference to the allocated memory(pointer)
}
//now you can call free on your memory
free(pointer);
ポインターが間違った場所を指すようにすることで、ポインター演算でメモリーリークを作成できます。これにより、指していたメモリーのチャンクへの参照がなくなります。
指しているデータが malloc() で割り当てられたか静的に割り当てられたかに関係なく、メモリ リークです。ただし、malloc() による動的メモリ リークは危険ですが、静的メモリ リークは無害です。
配列の外側を指すことは未定義の動作であることに注意してください: 何でも起こる可能性があります。異なる配列を指しているポインターでポインター演算を行うことも、未定義の動作です。
未定義の動作の例:
typedef struct
{
char array1 [6] = "hello";
char array2 [6] = "world";
} HelloWorld_t;
HelloWorld_t hw;
const char* ptr = hw.array1;
ptr += 6; /* undefined behavior, out of bounds of the original array */
puts(ptr); /* anything can happen here: the program may crash */
puts(array2 - 6); /* also undefined behavior */