14

Cでのポインターの使用に関して、いくつかの混乱/問題があります。簡単に理解できるように、以下にサンプルコードを配置しました。これらのコードの違いに注意してください。理解に問題がある場合は、フィードバックをお寄せください。

これは機能しません。

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

void process() {
    int *arr;
    arr=(int*)malloc(5*sizeof(int));
    arr=(int*){3,1,4,5,2};
    for(int z=0;z<5;z++) {
        printf("%d ",arr[z]);
    }
    printf("\n");
}

int main() {
    process();
    return 0;
}

しかし、これは機能します。

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

void process() {
    int *arr;
    arr=(int*)malloc(5*sizeof(int));
    arr=(int[]){3,1,4,5,2};
    for(int z=0;z<5;z++) {
        printf("%d ",arr[z]);
    }
    printf("\n");
}

int main() {
    process();
    return 0;
}

これも機能します。なんで?ここではメモリを割り当てませんでした。

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

void process() {
    int *arr;
    arr=(int[]){3,1,4,5,2};
    for(int z=0;z<5;z++) {
        printf("%d ",arr[z]);
    }
    printf("\n");
}

int main() {
    process();
    return 0;
}

なぜそれらは同じではないのですか?

    arr=(int*){3,1,4,5,2};
    arr=(int[]){3,1,4,5,2};

この個別の割り当て方法で使用せずに、整数ポインターの配列を初期化する他の方法はありますか?

arr[0]=3;
arr[1]=1;
arr[2]=4;
arr[3]=5;
arr[4]=2;

静的for(int z=0;z<NUM;z++) {ではなくのようなものを使用できるように、ポインタのメモリ内の割り当てのサイズ/数を取得するにはどうすればよいですか?for(int z=0;z<5;z++) {

どんな答えでも大歓迎です。

前もって感謝します。

4

3 に答える 3

16

最初のいくつかの例のmalloc呼び出しは、メモリのブロックを割り当て、そのメモリへのポインタをに割り当てますarr。再度割り当てるとすぐにarr、ポインタ値が上書きされ、割り当てられたメモリを追跡できなくなります。つまり、リークしたことになります。それはまさにそこにあるバグです。

つまり、usingを使用してメモリのブロックを割り当てる場合、malloc()配列構文を使用してメモリのブロックにデータを書き込むことができます(たとえば)。

int* arr = (int *) malloc(sizeof(int) * 5);
for (int i=0; i<5; ++i)
    arr[i] = i;

ただし、他のものを直接に割り当てることはできません。そうしないとarr、そのメモリブロックへのポインタが失われます。また、を使用してブロックを割り当てる場合は、不要になったときmalloc()にを使用してブロックを削除することを忘れないでくださいfree()

配列は整数へのポインタではありません。それは配列です。配列名は、ポインターを引数として受け入れる関数に引数として渡すと、「ポインターに減衰する」と言われますが、同じものではありません。

最後の質問に関して:これは実際には配列と型へのポインターの違いです。コンパイラーは配列のサイズを知っていますが、任意の型へのポインターが指すブロックのサイズを知りません。残念ながら、答えはノーです。

ただし、CではなくC ++を記述しているため、とにかく配列を使用しないでください。 `std ::vector'を使用してください。彼らは自分の長さを知っているだけでなく、拡張可能です。

于 2012-05-16T23:56:04.527 に答える
5

次のように言うと、データセグメント内のメモリptr = {1,2,3,4,5}ptrポイントします。このメモリには定数配列{1,2,3,4,5}が存在するため、メモリリークが発生します。割り当ての直後にメモリを初期化する場合は、次ptr[0]=1; ptr[1]=2;のように記述します。データをコピーする場合は、memcpyを使用してください。

于 2012-05-16T23:56:21.360 に答える
2

コンマ区切りの値のリストは、配列を初期化するための構造です。配列へのポインターの初期化には適していません。それが必要な理由です(int[])-提供された値で初期化される名前のない整数の配列を作成するように gcc に指示します。

arrgcc では、本当に必要でない限り、配列である情報を失うことはありません。そのため、キャストが必要です。arrポインターとしてではなく、配列として宣言することをお勧めします。ポインターを受け入れる関数に渡すこともできます。それでも、gcc は malloc でメモリをリークさせません:

error: incompatible types when assigning to type ‘int[5]’ from type ‘void *’

配列または割り当てられたメモリへのポインターのいずれかになる変数が必要な場合は、そのための別の変数を作成します。さらに良いのは、ポインタを受け取る関数を作成し、それを配列またはポインタのいずれかに渡すことです。

于 2013-11-25T22:17:00.827 に答える