Я нуждаюсь в помощи с 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
Вам нужно передать указатель на указатель в качестве параметра вашей функции.
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;
}
Это не имеет смысла:
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);
Как передать указатель на функцию и выделить память для переданного указателя изнутри вызываемого {{ 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(...);
}
Если вы хотите, чтобы ваша функция изменяла сам указатель, вам нужно передать его как указатель на указатель. Вот упрощенный пример:
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);
}
В исходном коде, когда вы передавали 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;
}
Вам нужно передать указатель по ссылке , а не копией , параметр в функции 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"); }