从我得到的答案中,我能够理解我在做什么错误。
我现在面临一个新问题,任何人都可以帮忙解决这个问题吗?
我想动态分配一个2D数组,所以我从我的main()
传递一个指针指向另一个名为alloc_2D_pixels(...)
的函数,我使用malloc(...)
和{ {1}}循环为2D数组分配内存。
好吧,从for(...)
函数返回后,指向指针的指针仍然保持为NULL,当我尝试访问或尝试alloc_2D_pixels(...)
指针到指针时,程序很自然挂起。
有人能告诉我我在这里犯的错误吗?
帮助!!!
维克拉姆
来源:
free(...)
答案 0 :(得分:3)
一个错误是发布无法编译的代码:)。以下是我的评论中的更正代码 / *这种风格* /:
/* 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);
}
答案 1 :(得分:2)
在alloc_2D_pixels
函数中,访问memory
时需要另一级间接。就像现在一样,您只修改参数,而不是参数指向的指针。例如,
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));
(基本上,在您使用memory
的任何地方,您需要使用(*memory)
;只有在使用下标时才需要括号,以确保以正确的顺序应用运算符)
答案 2 :(得分:1)
看起来,您使用的是未初始化的rows
和cols
变量
答案 3 :(得分:1)
在C中以这种方式使用多维数组对于性能来说是“次优的”。
没有不明确的词语:请不要使用 - 并且绝对不能初始化 - 以您所说明的方式初始化多维数组。多次调用malloc()
会产生一批不相交的内存位置不能很好地映射到实际图形(连续的单个缓冲区)如何存储在任何地方。此外,如果您必须执行数百次或数千次,malloc()
可能非常昂贵。
另外,由于您经常使用malloc(),因此清理也是一场噩梦(以及最终咬你的错误)。您甚至在代码中的注释中提到过,但是......为什么?
如果你绝对必须拥有这个ptr[rows][cols]
的东西,那就更好地创建它:
signed char alloc_2D_pixels(unsigned char*** memory,
unsigned int rows,
unsigned int cols)
{
int colspan = cols * sizeof(char);
int rowspan = rows * sizeof(char*);
unsigned char **rowptrs = *memory = malloc(rowspan + rows * colspan));
/* malloc failure handling left to the reader */
unsigned char *payload = ((unsigned char *)rowptrs) + rowspan;
int i;
for (i = 0; i < rows; payload += colspan, i++)
rowptrs[i] = payload;
}
这样你就只分配了一块内存,整个东西可以在一个去掉free_2D_pixels()
中释放。