如果我直接使用struct数组的名称进行分配,而不是函数参数,则代码可以工作。否则会返回内存错误。
typedef struct COORD
{
int xp;
int yp;
} coord;
coord** xy;
void allocate(coord** COORD)
{
int i;
//allocate COORD[500][460]
COORD = (coord**)malloc(sizeof(coord*)*500);
for(i=0; i<500; i++)
{
COORD[i] = (coord*)malloc(sizeof(coord)*460);
}
// freeing
for (i=0; i<500; i++) free(COORD[i]);
free(COORD);
}
//function call: allocate(xy);
//That is the code that leeds to the error
仅使用xy
代替COORD
。我不知道为什么这不起作用。
答案 0 :(得分:3)
您正在混合各种编码样式。目前尚不清楚您想要实现的目标。根据你的任务选择一个。
您需要一个应在堆上分配的大型临时缓冲区,而不需要从外部查看。只需创建一个局部变量:
void do_stuff(int w, int h)
{
coord **p;
int i;
p = malloc(h * sizeof(*p));
for (i = 0; i < h; i++) p[i] = malloc(w * sizeof(**p));;
// do stuff
for (i = 0; i < h; i++) free(p[i]);
free(p);
}
您希望分配客户端代码可以使用的存储空间。然后提供两个函数,一个分配,另一个释放内存:
coord **create(int w, int h)
{
coord **p;
int i;
p = malloc(h * sizeof(*p));
for (i = 0; i < h; i++) p[i] = malloc(w * sizeof(**p));
return p;
}
void destroy(coord **p, int h)
{
int i;
for (i = 0; i < h; i++) free(p[i]);
free(p);
}
您的客户端代码可以在这些调用之间使用内存:
coord **p = create(500, 460);
// do stuff
drestroy(p, 500);
(请注意,您必须将高度传递给destroy
,这有点不幸。创建一个包含宽度和高度以及指针信息的包装器结构可能更清晰。)
您有一个全局指针实例。然后你的功能总是在指针上运行,你不需要任何进一步的信息(尺寸除外):
coord **global = NULL;
void destroy_global(int h)
{
int i;
for (i = 0; i < h; i++) free(global[i]);
free(global);
global = NULL;
}
void create_global(int w, int h)
{
int i;
if (global != NULL) free_global();
global = alloc(h * sizeof(*global));
for (i = 0; i < h; i++) global[i] = malloc(w * sizeof(**global));
}
请注意,您应该为所有内存函数和<stdlib.h>
宏添加NULL
。
附录根据您的评论,您希望为位图分配内存。上面的选项2。
我建议创建一个对象结构。你可以将一个指针v作为句柄传递给一堆函数。您可以使用返回该句柄的函数创建对象。
下面简要介绍了位图对象的粗略设计。
typedef struct Pixel Pixel;
typedef struct Bitmap Bitmap;
struct Pixel {
uint8_t r, g, b;
};
struct Bitmap {
int height;
int width;
Pixel **pixel;
};
Bitmap *bitmap_new(int w, int h)
{
Bitmap *bmp = malloc(sizeof(*bmp));
int i;
bmp->height = h;
bmp->width = w;
bmp->pixel = malloc(h * sizeof(*bmp->pixel));
for (i = 0; i < h; i++) {
bmp->pixel[i] = malloc(w * sizeof(**bmp->pixel));
}
return p;
}
void bitmap_delete(Bitmap *bmp)
{
int i;
for (i = 0; i < h; i++) free(bmp->pixel[i]);
free(bmp->pixel);
free(bmp);
}
Bitmap *bitmap_read(const char *fn)
{
Bitmap *bmp;
FILE *f = fopen(fn, "rb");
// read and allocate
return bmp;
}
void bitmap_blank(Bitmap *bmp, int r, int g, int b)
{
for (i = 0; i < bitmap->height; i++) {
for (j = 0; j < bitmap->width; j++) {
bmp->pixel[i][j].r = r;
bmp->pixel[i][j].g = g;
bmp->pixel[i][j].b = b;
}
}
}
void bitmap_mirror_x(Bitmap *bmp)
{
// do stuff
}
int bitmap_write(Bitmap *bmp, const char *fn)
{
FILE *f = fopen(fn, "rb");
// write bitmap to file
return 0;
}
该设计类似于FILE *
的界面:fopen
为您提供句柄(或NULL
;上面的代码中省略了错误检查)和fread
, fprintf
,fseek
和family将指向文件的指针作为参数。最后调用fclose
关闭磁盘上的文件并释放fopen
声明的任何资源。
答案 1 :(得分:0)
问题是函数allocate()
无法在其外部更改xy
的值。这是因为C是call by value,被调用函数只获取其参数的值,而不是对调用者上下文中表达式的任何类型的引用。
需要:
void allocate(coord ***c)
{
}
和
coord **xy;
allocate(&xy);
当然是愚蠢的:正确的设计是allocate()
返回新地址:
coord ** allocate(void)
{
}
使用如下:
coord **xy = allocate();
将尺寸作为函数的参数可能会更好,因为幻数通常不是一件好事:
coord ** allocate(size_t width, size_t height);
答案 2 :(得分:0)
您是否尝试过编译此代码?有很多错误。
首先,main的类型总是是'int main(int argc,char * argv [])' 其次,你需要'#include&lt; stdlib.h&gt;'在你的文件的顶部,以获得malloc / free和朋友的返回类型。 第三,你没有宣称'我'。 第四,您使用相同名称“COORD”作为结构名称和变量。不要这样做,它会给你带来麻烦。
发送错误的代码使得很难弄清楚问题的根源是什么,但我怀疑这是“COORD”的超载。
答案 3 :(得分:0)
typedef struct COORD
{
int xp;
int yp;
} coord;
coord** xy;
void allocate(coord** COORD)
{
int i;
//allocate COORD[500][460]
COORD = (coord**)malloc(sizeof(coord*)*500);
for(i=0; i<500; i++)
{
COORD[i] = (coord*)malloc(sizeof(coord)*460);
}
// freeing
for (i=0; i<500; i++) free(COORD[i]);
free(COORD);
}
//function call: allocate();
//That is the code that works
答案 4 :(得分:0)
typedef struct
{
int xp;
int yp;
} Coord;
Coord **xy;
Coord** allocate(size_t height, size_t width)
{
int i;
Coord **arr;
arr = malloc(sizeof(Coord*)*height);
for(i=0; i<height; i++) {
arr[i] = malloc(sizeof(coord)*width);
}
return arr;
}
void allocate2(Coord ***p_arr, size_t height, size_t width)
{
int i;
Coord **arr;
arr = *p_arr;
arr = malloc(sizeof(Coord*)*height);
for(i=0; i<height; i++) {
arr[i] = malloc(sizeof(coord)*width);
}
}
void deallocate(Coord **arr, size_t height)
{
for (i=0; i<500; i++) {
free(arr[i]);
}
free(arr);
}
int main()
{
Coord **arr_2;
Coord ***p_arr_3;
allocate2(&xy, 500, 460);
/* do something with global array, xy, e.g. */
xy[1][2].xp = 100;
xy[1][2].yp = 200;
deallocate(xy, 500);
arr_2 = allocate(500, 460);
/* do something with local array, arr_2 */
deallocate(arr_2, 500);
allocate2(p_arr_3, 500, 460);
/* do something with ptr to local array, p_arr_3 */
deallocate(*p_arr_3, 500);
return 0;
}