[英]Passing struct array of pointers as a function argument?
如果我直接使用struct數組的名稱進行分配,而不是使用function參數,則該代碼有效。 否則返回內存錯誤。
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
。 我都想知道為什么這不起作用。
您在這里混合了各種編碼樣式。 目前尚不清楚您到底想要實現什么。 根據您的任務選擇一個。
您需要一個大的臨時緩沖區,該緩沖區應該在堆上分配,並且不需要從外部看到。 只需創建一個局部變量:
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);
(請注意,您必須將height傳遞給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));
}
請注意,對於所有內存功能和NULL
宏,都應包括<stdlib.h>
。
附錄根據您的評論,您想為位圖分配內存。 這是上面的選項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
聲稱擁有的所有資源。
問題在於,函數allocate()
無法在自身外部更改xy
的值。 這是因為C是按值調用的 ,被調用函數僅獲取其自變量的值,而不獲取調用方上下文中對表達式的任何引用。
它必須是:
void allocate(coord ***c)
{
}
和:
coord **xy;
allocate(&xy);
當然這是愚蠢的:正確的設計是讓allocate()
返回新地址:
coord ** allocate(void)
{
}
使用方式如下:
coord **xy = allocate();
最好將維度作為函數的參數,因為魔術數字通常不是一件好事:
coord ** allocate(size_t width, size_t height);
您是否嘗試過編譯此代碼? 有很多錯誤。
首先,main的類型應始終為'int main(int argc,char * argv [])'。其次,您需要在文件頂部使用'#include <stdlib.h>'以獲取malloc的返回類型。 / free和朋友。 第三,您不是在聲明“ i”。 第四,您使用相同的名稱“ COORD”作為結構名稱和變量。 不要這樣做,這會給您帶來麻煩。
發送不正確的代碼將很難弄清楚問題的根源是什么,但我懷疑這是“ COORD”的重載。
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
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.