gpt4 book ai didi

c - 函数中动态分配的结构

转载 作者:太空宇宙 更新时间:2023-11-04 04:13:56 25 4
gpt4 key购买 nike

我有一个与 bmp 相关的学校项目,我对事物的动态分配方面有点困惑(因为我被要求使用它)。我想做的是使用指针传递我的数组,以便即使在函数结束后数组也会更改其值,这就是我使用 ** 的原因。但是,代码最终会因为这一点而崩溃(如果没有它,它会顺利运行)。我确定这是我对 * 和 & 的错误使用,但我不知道在哪里以及如何修复它。

typedef struct pixel{unsigned int r,g,b;}pixel;
void liniarizare(char *filename,pixel **liniar)
{int i;
... (i calculate size which is surely correct and declare fin;size=width*height*sizeof(pixel)
*liniar=(pixel*)malloc(size);
for (i=0;i<width*height;i++)
{fread(&liniar[i]->b,1,1,fin);
fread(&liniar[i]->g,1,1,fin);
fread(&liniar[i]->r,1,1,fin);
}
}
...
int main()
{...
pixel *liniar
liniarizare(filename,&liniar);
....}

最佳答案

请注意,这是我的热门评论开头。

也就是说,让函数返回pixel *。并且,使用额外的 unsigned char 变量来防止将字节读入 unsigned int

这是我认为应该可行的简化版本:

typedef struct pixel {
unsigned int r;
unsigned int g;
unsigned int b;
} pixel;

pixel *
liniarizare(char *filename)
{
int i;

int count = width * height;
int size = sizeof(pixel) * count;
pixel *liniar = malloc(size);

pixel *pix = liniar;
unsigned char byte;
for (i = 0; i < count; ++i, ++pix) {
fread(&byte,1,1,fin);
pix->b = byte;

fread(&byte,1,1,fin);
pix->g = byte;

fread(&byte,1,1,fin);
pix->r = byte;
}

return liniar;
}

int
main(void)
{
pixel *liniar;

liniar = liniarizare(filename);

return 0;
}

更新:

Miraculously enough it works. The only problem is that i need to be able to pass the array by "reference" in the function and have the function provide back the modified array,which is why i insisted on using ** and a void. Do you have any idea what could be wrong in my code with your advice? You said something about linear[i]->b being wrong.

好的,处理“返回”双星参数(例如whatever **retptr)的最简单/最好的方法是尽可能地忽略它.

也就是说,该函数在内部处理更简单的whatever *ptr。这是更快,因为只有一个取消引用级别,不是每个语句上的双重取消引用。 p>

返回值(即双星指针)只在末尾设置一次

这是我修改后的示例,以使用您的原始函数原型(prototype) [但经过我的其他清理]。请注意,只有两行发生了变化(函数原型(prototype)和函数的最后一行):

typedef struct pixel {
unsigned int r;
unsigned int g;
unsigned int b;
} pixel;

void
liniarizare(char *filename,pixel **retval)
{
int i;

int count = width * height;
int size = sizeof(pixel) * count;
pixel *liniar = malloc(size);

pixel *pix = liniar;
unsigned char byte;
for (i = 0; i < count; ++i, ++pix) {
fread(&byte,1,1,fin);
pix->b = byte;

fread(&byte,1,1,fin);
pix->g = byte;

fread(&byte,1,1,fin);
pix->r = byte;
}

*retval = liniar;
}

int
main(void)
{
pixel *liniar;

liniarizare(filename,&liniar);

return 0;
}

有时“返回值”指针需要在函数的顶部读取并在底部设置。

这是一个单向链表的“push to tail”函数:

void
push(node **list,node *new)
{
node *head;
node *prev;
node *cur;

head = *list;

prev = NULL;
for (cur = head; cur != NULL; cur = cur->next)
prev = cur;

if (prev != NULL)
prev->next = new;
else
head = new;

new->next = NULL;

*list = head;
}

更新 #2:

好的,现在我们已经有了工作的东西,是时候优化了[在适当的休息时间之后:-)]。

保留当前可用的版本作为引用/交叉检查。

fread 对单个字节的调用有些昂贵。

由于您的代码是一次执行一个字节的 I/O,我们可以用 fgetc 替换 fread 调用。这应该稍微快一些:

for (i = 0; i < count; ++i, ++pix) {
pix->b = fgetc(fin) & 0xFF;
pix->g = fgetc(fin) & 0xFF;
pix->r = fgetc(fin) & 0xFF;
}

但是,我们希望尽可能多地阅读单个 block 。要在一次 fread 调用中读取整个 图像,需要一个临时数组(例如)unsigned char image[count];。这可能是 太多 内存,读取大图像可能会遇到缓存命中/未命中问题。

但是我们可以一次做一个(例如unsigned char row[width * 3];)。这更容易处理,可能会产生同样好的或更好的结果,因此它可能是一个很好的折衷方案。

可能也可能不会更快。这就是我们保留其他版本并进行基准测试以确定最快/最佳版本的原因。

请注意,此代码假定 X 维度中的像素在物理上是相邻的 [一种合理的可能性],但即使矩阵已转置,它仍然有效。最后,它仍然按照您的原始代码以线性顺序读取 count 像素:

typedef struct pixel {
unsigned int r;
unsigned int g;
unsigned int b;
} pixel;

void
liniarizare_by_row(char *filename,pixel **retval)
{
int i;
int yidx;

int count = width * height;
int size = sizeof(pixel) * count;
int w3 = width * 3;
pixel *liniar = malloc(size);

pixel *pix = liniar;
unsigned char row[w3];
for (yidx = 0; yidx < height; ++yidx) {
fread(row,sizeof(row),1,fin);
for (i = 0; i < w3; i += 3, ++pix) {
pix->b = row[i + 0];
pix->g = row[i + 1];
pix->r = row[i + 2]
}
}

*retval = liniar;
}

int
main(void)
{
pixel *liniar;
pixel *liniar_fast;

liniarizare(filename,&liniar);
liniarizare_fast(filename,&liniar_fast);

return 0;
}

关于c - 函数中动态分配的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54013617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com