web-dev-qa-db-ja.com

C NULLへのポインターの割り当て

私はCのポインターについて基本的なことを誤解しています。これは単純なはずですが、検索によって何も表示されません。次のコードの動作がわかりません。

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

void my_function(char *);

int main(int argc, char *argv[]) {
    char *ptr;
    ptr = malloc(10);

    if(ptr != NULL) printf("FIRST TEST: ptr is not null\n");
    else printf("FIRST TEST: ptr is null\n");

    my_function(ptr);

    if(ptr != NULL) printf("SECOND TEST: ptr is not null\n");
    else printf("SECOND TEST: ptr is null\n");
}

void my_function(char *a) {
    a = NULL;
}

どの出力;

FIRST TEST: ptr is not null
SECOND TEST: ptr is not null

2番目のテストでポインターがまだNULLでないと見なされるのはなぜですか?関数の特定の失敗を示す一種の「戻りフラグ」としてNULLポインター割り当てを使用しようとしています。しかし、後でポインタをテストすると、それはNULLではないようです。

12
lynks

これは、ポインタが参照ではなく値で渡されるためです。関数内のポインターを変更する場合は、実際のポインターをポインターとして、つまりポインターへのポインターとして渡す必要があります。

void my_function(char **a)
{
    *a = NULL;
}

関数を呼び出してポインタのアドレスを取得するときは、アドレス演算子&を使用します。

my_function(&ptr);
32

cでは、foo(a)のような関数呼び出しはaの値を変更しません。

2
richselian

関数はchar** aそれが指すものを変更したい場合。これは、ポインタが関数への引数としてコピーされたであるためです。つまり、内部で行った変更は、コピーを変更するため、関数の外部では表示されません。

これを変更して関数スコープの外に表示したい場合は、別の間接参照を追加する必要があります。

1
Tony The Lion

関数へのポインタを渡すと、ポインタは関数スコープにコピーされます。そのようなことをしたい場合は、ポインタのポインタを使用する必要があります。ポインタは基本的に整数/長整数型のみです

0
vszurma

あなたの問題は、my_pointerがポインタ "ptr"に書き込むのではなく、そのコピー "* a"に書き込むことです。

「ptr」のアドレスを必要なものに渡す必要があります。

0
user2054656