簡體   English   中英

將指針的struct數組作為函數參數傳遞?

[英]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 ;上面的代碼中省略了錯誤檢查), freadfprintffseek和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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM