C Программирование: malloc () в другой функции

Я нуждаюсь в помощи с malloc() в другой функции.

Я передаю указатель и размер к функции от моего main() и я хотел бы выделить память для того указателя динамично с помощью malloc() из той вызванной функции, но то, что я вижу, - то, что.... память, которая становится выделенной, для указателя, объявленного в моей вызванной функции а не для указателя, который является в main().

Как я должен передать указатель на функцию и выделить память для переданного указателя из вызванной функции?


Я написал следующий код, и я получаю вывод как показано ниже.

ИСТОЧНИК:

int main()
{
   unsigned char *input_image;
   unsigned int bmp_image_size = 262144;

   if(alloc_pixels(input_image, bmp_image_size)==NULL)
     printf("\nPoint2: Memory allocated: %d bytes",_msize(input_image));
   else
     printf("\nPoint3: Memory not allocated");     
   return 0;
}

signed char alloc_pixels(unsigned char *ptr, unsigned int size)
{
    signed char status = NO_ERROR;
    ptr = NULL;

    ptr = (unsigned char*)malloc(size);

    if(ptr== NULL)
    {
        status = ERROR;
        free(ptr);
        printf("\nERROR: Memory allocation did not complete successfully!");
    }

    printf("\nPoint1: Memory allocated: %d bytes",_msize(ptr));

    return status;
}

ПРОГРАММА ПРОИЗВЕЛА:

Point1: Memory allocated ptr: 262144 bytes
Point2: Memory allocated input_image: 0 bytes
61
задан Jonathan Leffler 31 May 2016 в 18:17
поделиться

6 ответов

Вам нужно передать указатель на указатель в качестве параметра вашей функции.

int main()
{
   unsigned char *input_image;
   unsigned int bmp_image_size = 262144;

   if(alloc_pixels(&input_image, bmp_image_size) == NO_ERROR)
     printf("\nPoint2: Memory allocated: %d bytes",_msize(input_image));
   else
     printf("\nPoint3: Memory not allocated");     
   return 0;
}

signed char alloc_pixels(unsigned char **ptr, unsigned int size) 
{ 
    signed char status = NO_ERROR; 
    *ptr = NULL; 

    *ptr = (unsigned char*)malloc(size); 

    if(*ptr== NULL) 
    {
        status = ERROR; 
        free(*ptr);      /* this line is completely redundant */
        printf("\nERROR: Memory allocation did not complete successfully!"); 
    } 

    printf("\nPoint1: Memory allocated: %d bytes",_msize(*ptr)); 

    return status; 
} 
73
ответ дан 24 November 2019 в 17:01
поделиться

Это не имеет смысла:

if(alloc_pixels(input_image, bmp_image_size)==NULL) 

alloc_pixels возвращает знаковый символ ( ОШИБКА или NO_ERROR ), и вы сравниваете его с NULL (который предполагается использовать для указателей).

Если вы хотите изменить input_image , вам нужно передать указатель на него в alloc_pixels . Подпись alloc_pixels будет следующее:

signed char alloc_pixels(unsigned char **ptr, unsigned int size)

Вы бы назвали это так:

alloc_pixels(&input_image, bmp_image_size);

И распределение памяти

*ptr = malloc(size);
2
ответ дан 24 November 2019 в 17:01
поделиться

Как передать указатель на функцию и выделить память для переданного указателя изнутри вызываемого {{ 1}}?

Спросите себя: если бы вам пришлось написать функцию, которая должна возвращать int , как бы вы это сделали?

Вы бы либо вернули ее напрямую:

int foo(void)
{
    return 42;
}

или вернуть его через выходной параметр, добавив уровень косвенного обращения (т. Е., используя int * вместо int ):

void foo(int* out)
{
    assert(out != NULL);
    *out = 42;
}

Итак, когда вы возвращаете тип указателя ( T * ), это то же самое: вы либо напрямую возвращаете тип указателя:

T* foo(void)
{
    T* p = malloc(...);
    return p;
}

, либо добавляете один уровень косвенности:

void foo(T** out)
{
    assert(out != NULL);
    *out = malloc(...);
}
90
ответ дан 24 November 2019 в 17:01
поделиться

Если вы хотите, чтобы ваша функция изменяла сам указатель, вам нужно передать его как указатель на указатель. Вот упрощенный пример:

void allocate_memory(char **ptr, size_t size) {
    void *memory = malloc(size);
    if (memory == NULL) {
        // ...error handling (btw, there's no need to call free() on a null pointer. It doesn't do anything.)
    }

    *ptr = (char *)memory;
}

int main() {
   char *data;
   allocate_memory(&data, 16);
}
8
ответ дан 24 November 2019 в 17:01
поделиться

В исходном коде, когда вы передавали input_image в функцию alloc_pixels, компилятор создавал его копию (то есть ptr) и сохранял значение в стеке. Вы назначаете значение, возвращаемое malloc, для ptr. Это значение теряется, когда функция возвращается в основную и стек раскручивается. Таким образом, память по-прежнему выделяется в куче, но эта ячейка памяти никогда не сохранялась (или не назначалась) input_image, отсюда и проблема.

Вы можете изменить сигнатуру функции alloc_pixels, что будет проще для понимания, и вам также не потребуется дополнительная переменная status.

unsigned char *alloc_pixels(unsigned int size)
{
    unsigned char *ptr = NULL;
    ptr = (unsigned char *)malloc(size);
    if (ptr != NULL)
       printf("\nPoint1: Memory allocated: %d bytes",_msize(ptr));
    return ptr;
}

Вы можете вызвать указанную выше функцию в main:

int main()
{
   unsigned char *input_image;
   unsigned int bmp_image_size = 262144;

   if((input_image = alloc_pixels(bmp_image_size))==NULL)
       printf("\nPoint3: Memory not allocated");    
   else
     printf("\nPoint2: Memory allocated: %d bytes",_msize(input_image)); 
   return 0;

}
1
ответ дан 24 November 2019 в 17:01
поделиться

Вам нужно передать указатель по ссылке , а не копией , параметр в функции alloc_pixels требует амперсанда &, чтобы передать обратно адрес указателя - то есть вызов по ссылке на языке C.

main()
{
   unsigned char *input_image;
   unsigned int bmp_image_size = 262144;

   if(alloc_pixels(&input_image, bmp_image_size)==NULL)
     printf("\nPoint2: Memory allocated: %d bytes",_msize(input_image));
   else
     printf("\nPoint3: Memory not allocated");     

}

signed char alloc_pixels(unsigned char **ptr, unsigned int size)
{
    signed char status = NO_ERROR;
    *ptr = NULL;

    *ptr = (unsigned char*)malloc(size);

    if((*ptr) == NULL)
    {
        status = ERROR;
        /* free(ptr);
        printf("\nERROR: Memory allocation did not complete successfully!"); */
    }

    printf("\nPoint1: Memory allocated: %d bytes",_msize(*ptr));

    return status;
}

Я закомментировал две строки бесплатно (ptr) и «ОШИБКА: ..."внутри функции alloc_pixels , так как это сбивает с толку. Вам не нужно освободить указатель, если выделение памяти не удалось.

Изменить: После просмотра ] msdn ссылка предоставлена ​​OP, предложение, образец кода такой же, как и ранее в моем ответе .... но ... измените спецификатор формата на % u для size_t в вызове printf (...) в main () .

main()
{
   unsigned char *input_image;
   unsigned int bmp_image_size = 262144;

   if(alloc_pixels(&input_image, bmp_image_size)==NULL)
     printf("\nPoint2: Memory allocated: %u bytes",_msize(input_image));
   else
     printf("\nPoint3: Memory not allocated");     

}
4
ответ дан 24 November 2019 в 17:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: