简体   繁体   English

将指针的struct数组作为函数参数传递?

[英]Passing struct array of pointers as a function argument?

The code works if i use the name of the struct array directly for the allocation, but not from the function argument. 如果我直接使用struct数组的名称进行分配,而不是使用function参数,则该代码有效。 Otherwise it returns memory error. 否则返回内存错误。

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

Using just xy instead of COORD works. 仅使用xy代替COORD And i am all wondering why is that not working. 我都想知道为什么这不起作用。

You are mixing up various coding styles here. 您在这里混合了各种编码样式。 It's not clear what exactly you want to achieve. 目前尚不清楚您到底想要实现什么。 Pick one according to your task. 根据您的任务选择一个。

Temporary buffer 临时缓冲区

You need a large temporary buffer that should be allocated on the heap and that does not need to be seen from outside. 您需要一个大的临时缓冲区,该缓冲区应该在堆上分配,并且不需要从外部看到。 Just create a local variable: 只需创建一个局部变量:

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);
}

Allocate memory for further use 分配内存以备将来使用

You want to allocate storage that your client code can use. 您想要分配客户端代码可以使用的存储。 Then provide two functions, one that allocates and one that frees the memory: 然后提供两个功能,一个分配功能,另一个释放内存:

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);
}

Your client code can then use the memory between these calls: 然后,您的客户端代码可以在这些调用之间使用内存:

coord **p = create(500, 460);

// do stuff

drestroy(p, 500);

(Note that you have to pass the height to destroy , which is a bit unfortunate. It might be cleaner to create a wrapper struct that hold information about width and height and the pointer.) (请注意,您必须将height传递给destroy ,这有点不幸。创建包含宽度和高度以及指针信息的包装器结构可能会更干净。)

Allocate memory for a global variable 为全局变量分配内存

You have a single instance of a global pointer. 您只有一个全局指针实例。 Then your functions always operate on that pointer and you don't need any further information on it (except the dimensions): 然后,您的函数将始终在该指针上运行,并且您不需要任何其他信息(尺寸除外):

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));        
}

Note that you should include <stdlib.h> for all memory functions and the NULL macro. 请注意,对于所有内存功能和NULL宏,都应包括<stdlib.h>

Addendum According to your comment, you want to allocate memory for a bitmap. 附录根据您的评论,您想为位图分配内存。 That's option 2 above. 这是上面的选项2。

I recommend to create an object structure. 我建议创建一个对象结构。 You can pass a pointerv to that structure as handle to a bunch of functions. 您可以将指标v传递给该结构,以作为一堆函数的句柄。 You can create the object with a function that returns that handle. 您可以使用返回该句柄的函数来创建对象。

The following sketches a rough design for a bitmap object. 下面概述了位图对象的粗略设计。

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;
}

The design is similar to the interface to FILE * : fopen gives you a handle (or NULL ; error checking is omitted in the code above) and fread , fprintf , fseek and family take a pointer to the file as argument. 该设计类似于FILE *的接口: fopen为您提供一个句柄(或NULL ;上面的代码中省略了错误检查), freadfprintffseek和family以指向该文件的指针作为参数。 Finally call fclose to close the file on disk and to free any ressources fopen has claimed. 最后,调用fclose关闭磁盘上的文件并释放fopen声称拥有的所有资源。

The problem is that the function allocate() cannot change the value of xy outside itself. 问题在于,函数allocate()无法在自身外部更改xy的值。 This is because C is call by value , the called function only gets the values of its arguments, not any kind of references to the expressions in the caller's context. 这是因为C是按值调用的 ,被调用函数仅获取其自变量的值,而不获取调用方上下文中对表达式的任何引用。

It needs to be: 它必须是:

void allocate(coord ***c)
{
}

and: 和:

coord **xy;
allocate(&xy);

which of course is silly: the proper design would be for allocate() to return the new address: 当然这是愚蠢的:正确的设计是让allocate() 返回新地址:

coord ** allocate(void)
{
}

with use like: 使用方式如下:

coord **xy = allocate();

Probably it would be even better to have the dimensions as parameters to the function, since magic numbers are generally not a good thing: 最好将维度作为函数的参数,因为魔术数字通常不是一件好事:

coord ** allocate(size_t width, size_t height);

Have you tried to compile this code? 您是否尝试过编译此代码? There are a number of errors. 有很多错误。

First, the type of main should always be 'int main(int argc, char *argv[])' Second, you need to '#include <stdlib.h>' at the top of your file to get the return type of malloc/free and friends. 首先,main的类型应始终为'int main(int argc,char * argv [])'。其次,您需要在文件顶部使用'#include <stdlib.h>'以获取malloc的返回类型。 / free和朋友。 Third, you are not declaring 'i'. 第三,您不是在声明“ i”。 Fourth, you are using the same name 'COORD' as both a struct name and as a variable. 第四,您使用相同的名称“ COORD”作为结构名称和变量。 Don't do this, it will cause you problems. 不要这样做,这会给您带来麻烦。

Sending incorrect code makes it very difficult to figure out what the root of your problem is, but I suspect it's the overloading of '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