0

関数にメモリのブロックを割り当て、引数の1つを介してそのブロックへのポインターを返す方法を見つけようとしています。これは C プログラムです。何か困っているようです。コードは次のとおりです。

void foo(char *ptr)
{
     if (!(ptr = malloc(size)))
          printf("error");

     /* code here */

     printf("buffer address: %i\n", (int)buffer);
}

int main()
{
     char *ptr;
     ptr = NULL;

     foo(ptr);

     printf("buffer address: %i\n", (int)buffer);
}

結果は次のとおりです。

buffer address: 142385160
buffer address: 0

しかし、私は次のようなものを期待していました:

buffer address: 142385160
buffer address: 142385160

私は何を間違っていますか?

4

7 に答える 7

5

他の人はポインタをポインタに渡すことを示しましたが、より簡単なオプションがあなたの質問で示されています:

関数にメモリのブロックを割り当て、そのブロックへのポインターを返す方法を理解しようとしています。

(私のものを強調してください。)

何かを返すことを考えるときは、それを戻り値として使用してみてください:)

char* foo()
{
    char* ptr;
    if (!(ptr = malloc(size)))
        printf("error");

    /* code here */

    printf("buffer address: %i\n", (int)ptr);
    return ptr;
}

void*(代わりに戻ることも検討してくださいchar*)

他の理由ですでに戻り値がある場合、「ポインターへのポインター」アプローチを使用するのが適切かもしれませんが、元の値を使用しておらず、何かを返すだけの場合は、物事をシンプルに保つ価値があると思いますできれば。

于 2009-09-28T07:05:39.683 に答える
3

あなたの質問が述べているように、ポインタを返さないのはなぜですか:

void* foo(void)
{
     void* ptr = malloc(size);
     if (!ptr)
          printf("error");

     /* code here */

     printf("buffer address: %p\n", ptr);
}

int main(void)
{
     char *ptr = foo();

     printf("buffer address: %p\n", (void*)ptr);
}

(私が行った他の編集は、変数の型を変更するか、明示的なキャストを介して、すべてprintfのポインター型が使用され、型%pが渡されることを確認することでした。また、必要に応じて変数宣言に初期化を追加しました。)void*

于 2009-09-28T07:05:45.083 に答える
3

(int)buffer が (int)ptr であると仮定すると、参照ではなく値でポインターを渡しているため、関数で行われた変更は外部には影響しません。

次のいずれかの結果を返すことができます。

char *foo()
{
     if (!(ptr = malloc(size)))
          printf("error");

     /* code here */

     printf("buffer address: %i\n", (int)ptr);
     return ptr;
}

int main()
{
     char *ptr;
     ptr = NULL;

     ptr = foo();

     printf("buffer address: %i\n", (int)ptr);
}

またはポインタを参照で渡す

void foo(char **ptr)
{
     if (!(*ptr = malloc(size)))
          printf("error");

     /* code here */

     printf("buffer address: %i\n", (int)*ptr);
}

int main()
{
     char *ptr;
     ptr = NULL;

     foo(&ptr);

     printf("buffer address: %i\n", (int)ptr);
}
于 2009-09-28T07:05:46.063 に答える
2

ポインタは変数です。C のすべての変数は、によって渡されます。観察:

void test(int i)
{
    printf("Before: %i\n", i);
    i = 0;
    printf("After:  %i\n", i);
}

int main(void)
{
    int i = 5;
    printf("Before: %i\n", i);
    test(i);
    printf("After:  %i\n", i);
}

版画:

Before: 5
Before: 5
After:  0
After:  5

ポインタも同じように機能します。ポインター自体を変更しても、呼び出し元のポインターは変更されません。ポインターの利点は、ポインターの内容を変更できることです。いくつかのオプションがあります:

void foo(char **ptr)
{
    if (!(*ptr = malloc(size)))
        printf("error");

    /* code here */

    printf("buffer address: %p\n", ptr);
}

int main()
{
    char *ptr;
    ptr = NULL;

    foo(&ptr);

    printf("buffer address: %p\n", *ptr);
}

または:

char *foo(char *ptr)
{
    if (!(ptr = malloc(size)))
        printf("error");

    /* code here */

    printf("buffer address: %p\n", ptr);
    return ptr;
}

int main()
{
    char *ptr;
    ptr = NULL;

    ptr = foo(ptr);

    printf("buffer address: %p\n", ptr);
}

どちらを使用するかは、何をするかによって異なりますfoo()。最も論理的な意味を持つものを選択してください。

于 2009-09-28T07:06:14.283 に答える
1

次のように、ポインターを char へのポインターに渡す必要があります。

void foo(char **ptr)
{
  // ...
  *ptr = result of malloc;
}

またはさらに良いことに、次のように戻ります。

void char * foo(int memsize)
{

}
于 2009-09-28T07:01:58.160 に答える
1

関数で、ポインターのローカル コピーを再割り当てします。呼び出し元の関数でポインターを再割り当てするには、ポインターが指すアドレスではなく、ポインターのアドレスを渡す必要があります。

void foo(char **ptr)
{
     if (!(*ptr = malloc(size)))
          printf("error");

     /* code here */

     printf("buffer address: %i\n", (int)*buffer);
}

int main()
{
     char *ptr;
     ptr = NULL;

     foo(&ptr); // pass address of your ptr, rather than it's value

     printf("buffer address: %i\n", (int)buffer);
}
于 2009-09-28T07:02:44.650 に答える
0

もう1つの単純化は次のようになります。

void *fun()
{
  return(malloc(sizeof(char)));
}


int main()
{
  char *foo = (char *) fun();
  printf("\n%p\n",foo);
}
于 2009-09-30T09:30:28.897 に答える