вчера я отправил вопрос: Как я должен передать указатель на функцию и выделить память для переданного указателя из вызванной функции?
Из ответов я добрался, я смог понять то, что путает, я делал.
Я сталкиваюсь с новой проблемой теперь, кто-либо может выручить с этим?
Я хочу динамично выделить 2D массив, таким образом, я передаю От указателя к указателю от моего main()
к другой вызванной функции alloc_2D_pixels(...)
, где я использую malloc(...)
и for(...)
цикл для выделения памяти для 2D массива.
Ну, после возврата из alloc_2D_pixels(...)
функция, от указателя к указателю все еще остается ПУСТЫМ, так естественно, когда я пытаюсь получить доступ или пытаюсь free(...)
От указателя к указателю, программа зависает.
Кто-либо может предложить меня, что путает, я делаю здесь?
На помощь!!!
Vikram
ИСТОЧНИК:
main()
{
unsigned char **ptr;
unsigned int rows, cols;
if(alloc_2D_pixels(&ptr, rows, cols)==ERROR) // Satisfies this condition
printf("Memory for the 2D array not allocated"); // NO ERROR is returned
if(ptr == NULL) // ptr is NULL so no memory was allocated
printf("Yes its NULL!");
// Because ptr is NULL, with any of these 3 statements below the program HANGS
ptr[0][0] = 10;
printf("Element: %d",ptr[0][0]);
free_2D_alloc(&ptr);
}
signed char alloc_2D_pixels(unsigned char ***memory, unsigned int rows, unsigned int cols)
{
signed char status = NO_ERROR;
memory = malloc(rows * sizeof(unsigned char** ));
if(memory == NULL)
{
status = ERROR;
printf("ERROR: Memory allocation failed!");
}
else
{
int i;
for(i = 0; i< cols; i++)
{
memory[i] = malloc(cols * sizeof(unsigned char));
if(memory[i]==NULL)
{
status = ERROR;
printf("ERROR: Memory allocation failed!");
}
}
}
// Inserted the statements below for debug purpose only
memory[0][0] = (unsigned char)10; // I'm able to access the array from
printf("\nElement %d",memory[0][0]); // here with no problems
return status;
}
void free_2D_pixels(unsigned char ***ptr, unsigned int rows)
{
int i;
for(i = 0; i < rows; i++)
{
free(ptr[i]);
}
free(ptr);
}
Одна ошибка - отправка кода, который не компилируется :). Ниже приведен исправленный код с моими комментариями в
/ * этот стиль * /:
/* Next four lines get your code to compile */
#include <stdio.h>
#include <stdlib.h>
#define NO_ERROR 0
#define ERROR 1
/* prototypes for functions used by main but declared after main
(or move main to the end of the file */
signed char alloc_2D_pixels(unsigned char*** memory, unsigned int rows, unsigned int cols);
void free_2D_pixels(unsigned char** ptr, unsigned int rows);
/* main should return int */
int main()
{
unsigned char** ptr;
/* need to define rows and cols with an actual value */
unsigned int rows = 5, cols = 5;
if(alloc_2D_pixels(&ptr, rows, cols) == ERROR) // Satisfies this condition
printf("Memory for the 2D array not allocated"); // ERROR is returned
if(ptr == NULL) // ptr is NULL so no memory was allocated
printf("Yes its NULL!");
else
{
/* Added else clause so below code only runs if allocation worked. */
/* Added code to write to every element as a test. */
unsigned int row,col;
for(row = 0; row < rows; row++)
for(col = 0; col < cols; col++)
ptr[0][0] = (unsigned char)(row + col);
/* no need for &ptr here, not returning anything so no need to pass
by reference */
free_2D_pixels(ptr, rows);
}
return 0;
}
signed char alloc_2D_pixels(unsigned char*** memory, unsigned int rows, unsigned int cols)
{
signed char status = NO_ERROR;
/* In case we fail the returned memory ptr will be initialized */
*memory = NULL;
/* defining a temp ptr, otherwise would have to use (*memory) everywhere
ptr is used (yuck) */
unsigned char** ptr;
/* Each row should only contain an unsigned char*, not an unsigned
char**, because each row will be an array of unsigned char */
ptr = malloc(rows * sizeof(unsigned char*));
if(ptr == NULL)
{
status = ERROR;
printf("ERROR: Memory allocation failed!");
}
else
{
/* rows/cols are unsigned, so this should be too */
unsigned int i;
/* had an error here. alloced rows above so iterate through rows
not cols here */
for(i = 0; i < rows; i++)
{
ptr[i] = malloc(cols * sizeof(unsigned char));
if(ptr[i] == NULL)
{
status = ERROR;
printf("ERROR: Memory allocation failed!");
/* still a problem here, if exiting with error,
should free any column mallocs that were
successful. */
}
}
}
/* it worked so return ptr */
*memory = ptr;
return status;
}
/* no need for *** here. Not modifying and returning ptr */
/* it also was a bug...would've needed (*ptr) everywhere below */
void free_2D_pixels(unsigned char** ptr, unsigned int rows)
{
/* should be unsigned like rows */
unsigned int i;
for(i = 0; i < rows; i++)
{
free(ptr[i]);
}
free(ptr);
}
В вашей функции alloc_2D_pixels
нужен еще один уровень непрямого доступа к памяти
. В нынешнем виде вы изменяете только параметр, а не указатель, на который указывает параметр. Например,
memory = malloc(rows * sizeof(unsigned char** ));
// becomes
*memory = malloc(rows * sizeof(unsigned char** ));
// and later...
memory[i] = malloc(cols * sizeof(unsigned char));
// becomes
(*memory)[i] = malloc(cols * sizeof(unsigned char));
(по сути, везде, где вы используете память
, вам нужно использовать (*память)
; круглые скобки нужны только при использовании подскриптов, чтобы убедиться, что операторы применяются в правильном порядке)
Также похоже, что вы используете неинициализированные строки
и столбцы
переменные