Проблема с передачей указателя на функцию в C - PullRequest
0 голосов
/ 26 апреля 2011

Это одна из тех раздражающих вещей, когда вы знаете, что ответ прост, но вы просто не можете его увидеть.

Оператор printf в AllocIntArray показывает, что arrayPtr правильно назначается область памяти, однако, когда выполняется оператор printf в main, он показывает, что arrayB по-прежнему имеет значение NULL.

Может кто-нибудь показать мне, что я делаю неправильно, передавая arrayB в AllocIntArray?

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

void AllocIntArray(int *arrayPtr, int numElements);

int main()
{
   int *arrayB = NULL;

   AllocIntArray(arrayB, 10);
   printf("Pointer: %p\n", arrayB);

   free(arrayB);

   getchar();
   return EXIT_SUCCESS;
}

void AllocIntArray(int *arrayPtr, int numElements)
{
   arrayPtr = (int *)malloc(sizeof(int) * numElements);
   printf("Pointer: %p\n", arrayPtr);

   if(arrayPtr == NULL)
   {
      fprintf(stderr, "\nError allocating memory using malloc");
      exit(EXIT_FAILURE);
   }
}

Ответы [ 5 ]

4 голосов
/ 26 апреля 2011

Передайте двойной указатель.

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

void AllocIntArray(int **arrayPtr, int numElements);

int main()
{
   int *arrayB = NULL;

   AllocIntArray(&arrayB, 10);
   printf("Pointer: %p\n", arrayB);

   free(arrayB);

   getchar();
   return EXIT_SUCCESS;
}

void AllocIntArray(int **arrayPtr, int numElements)
{
   *arrayPtr = malloc(sizeof(int) * numElements);
   printf("Pointer: %p\n", *arrayPtr);

   if(*arrayPtr == NULL)
   {
      fprintf(stderr, "\nError allocating memory using malloc");
      exit(EXIT_FAILURE);
   }
}
2 голосов
/ 26 апреля 2011

Это потому, что arrayB передается AllocIntArray по значению. Либо передайте его по ссылке (с указателем на указатель), либо, лучше, верните его из AllocIntArray:

int *AllocIntArray(int numElements)
{
   int *arrayPtr = malloc(sizeof(int) * numElements);
   printf("Pointer: %p\n", arrayPtr);

   if(arrayPtr == NULL)
   {
      fprintf(stderr, "\nError allocating memory using malloc");
      exit(EXIT_FAILURE);
   }
   return arrayPtr;
}
0 голосов
/ 03 марта 2018

Основная проблема здесь в том, что вы передаете функцию arrayB в AllocIntArray как переданную по значению. В AllocIntArray она правильно распределяет память, а arrayptr действует, но в функции main это не та же память, котораявы ожидаете.Это базовая концепция программирования на Си, и вы можете проверить, добавляя печать в обе функции.

EX: Я делю разницу между проблемой и успешным случаем с примером ниже.

/*Code with passed by value as a parameter*/ 
#include<stdio.h>
#include<stdlib.h>
void AllocateIntarray(int *arrayptr,int numElements)
{
     arrayptr = (int*) malloc(sizeof(int)*numElements);
     printf("Inside _func_AllocateIntarray_pointer:%p\n",arrayptr);

     if(arrayptr == NULL)
     {
         printf("ERR_MEM_ALLOCATION_FAILED:\n");
     }
}

int main()
{
     int *arrayB = NULL;
     AllocateIntarray(arrayB,10);
     printf("Inside _func_mainPointer:%p\n",arrayB);

     free(arrayB);
     return 0;
 }
/*Output :
 Inside _func_AllocateIntarray_pointer:0x55be51f96260
 Inside _func_mainPointer:(nil)*/

Код с переданным по ссылке и с использованием двойного указателя.

#include<stdio.h>
#include<stdlib.h>
void AllocateIntarray(int **arrayptr,int numElements)
{
     *arrayptr =  malloc(sizeof(int)*numElements);
     printf("Inside _func_AllocateIntarray_pointer:%p\n",*arrayptr);

     if(*arrayptr == NULL)
     {
          printf("ERR_MEM_ALLOCATION_FAILED:\n");
     }
 }
 int main()
 {
     int *arrayB = NULL;
     AllocateIntarray(&arrayB,10);
     printf("Inside _func_mainPointer:%p\n",arrayB);

     free(arrayB);
     return 0;
  }
  /*Output :
    Inside _func_AllocateIntarray_pointer:0x562bacd1f260
    Inside _func_mainPointer:0x562bacd1f260*/
0 голосов
/ 26 апреля 2011

Вам нужно немного освежить порядок передачи параметров в функции.

Указатель, который вы отправляете в AllocIntArray, копируется в arrayPtr, строка

   arrayPtr = (int *)malloc(sizeof(int) * numElements);

присваивает копии значение, а не исходную переменную, и, следовательно, исходная переменная по-прежнему указывает на никуда.

Первое решение, которое приходит на ум, - это отправить указатель на этот указатель, но я думаю, что вам лучше немного разобраться в вопросе передачи параметров, прежде чем идти намного дальше.

0 голосов
/ 26 апреля 2011

arrayPtr является указателем, а указатель передается значением параметру. AllocIntArray может изменить свою версию arrayPtr, но изменения не будут видны main().

(Правка: если вы используете C ++), изменение подписи для AllocIntArray для изменения типа arrayPtr на ссылку должно решить вашу проблему.

void AllocIntArray(int *&arrayPtr, int numElements)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...