gpt4 book ai didi

将 1d 缓冲区重新组织为 2d 数组时崩溃

转载 作者:太空宇宙 更新时间:2023-11-04 05:57:33 24 4
gpt4 key购买 nike

我有一个 1d 缓冲区,我必须重新组织它才能作为 2d 数组访问。我在下面粘贴了我的代码:

#include <stdlib.h>
#include <stdio.h>

void alloc(int ** buf, int r, int c)
{
int **temp=buf;
for(int i=0; i<r; i++)
buf[i]=(int *)temp+i*c;
}
void main()
{
int *buffer=(int *)malloc(sizeof(int)*100);
int **p = (int**) buffer;
alloc(p, 4, 4);
//for(int i=0;i<r;i++)
//for(int j=0;j<c;j++)
// printf("\n %p",&p[i][j]);


p[0][3]=10;
p[2][3]=10;
p[3][2]=10; //fails here
printf("\n %d", p[2][3]);
}

当我进行分配时,代码崩溃了。我已经为不同的测试用例运行了代码。我观察到,当对 p[0][x] 进行赋值,然后对 p[x][anything] 进行赋值时,代码会崩溃,而代码会在第二次赋值时崩溃。仅当第一个赋值的第一个索引为 0 时才会看到此崩溃,并且没有其他索引发生崩溃,第二个赋值的第一个索引等于第一个赋值的第二个索引。

例如,在上面的代码中,崩溃发生在 p[0][3] 执行后的 p[3][2] 处。如果我将第一个赋值更改为 p[0][2],那么崩溃将发生在 p[2][3](或 p[2][anything] 处)。

我已经检查了 p 指向的内存,通过取消对双循环的注释,它似乎没问题。我怀疑在非法内存位置写入,但上述观察结果排除了这种可能性。

最佳答案

问题是您的二维数组实际上是指向数组的指针数组。这意味着您需要为指针留出空间。目前你的指针位于数组中的位置 0-3,但 p[0] 也指向位置 0。当你写入 'p[0,3]' 时,你正在覆盖p[3]

修复它的一种(诱人的)方法是在数组的开头留出指针空间。因此,您可以更改 alloc 方法以在前面留出一些空间。像这样的东西:

buf[i] = (int *)(temp+r) + i*c;

注意 +r 添加到 temp。它需要在转换之前添加到 temp,因为您不能假设 intint * 是同一类型。

我不推荐这种方法,因为您仍然必须记住在原始 malloc 中分配额外的空间来说明指针数组。这也意味着您不仅仅是将一维数组转换为二维数组。

另一种选择是将您的数组分配为指向单独分配的数组的指针数组。这是分配二维数组的正常方法。但是,这不会像您在一维数组中那样生成连续的数据数组。

在这两个选项之间,您可以分配一个额外的指针数组来保存您需要的指针,然后将它们指向数据。将您的 alloc 更改为:

int **alloc(int * buf, int r, int c)
{
int **temp = (int **)malloc(sizeof (int *)* r);
for (int i = 0; i<r; i++)
temp[i] = buf + i*c;
return temp;
}

然后你可以这样调用它:

int **p = alloc(buffer, 4, 4);

您还需要释放额外的缓冲区。

通过这种方式,您的数据和访问它所需的指针保持分离,并且您可以保持原始一维数据连续。

请注意,您不需要在 c 中转换 malloc 的结果,事实上有人说您不应该这样做。

另请注意,此方法消除了对转换指针的所有要求,任何消除转换需求的方法都是好事。

关于将 1d 缓冲区重新组织为 2d 数组时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24484735/

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