C++ 将1d缓冲区重新组织为2d数组

C++ 将1d缓冲区重新组织为2d数组,c++,c,arrays,pointers,C++,C,Arrays,Pointers,我得到了一个足够大的1d缓冲区(int buffer[100])。我需要重新组织与2d数组相同的内存。我要做的是将它键入一个双指针(int**p),然后将指针传递给将执行重新组织的alloc函数。函数返回后,我需要语句p[2][2]才能工作 代码如下: #include <stdlib.h> #include <stdio.h> void alloc(int ** buf, int r, int c) { int **temp; temp=buf;

我得到了一个足够大的1d缓冲区(
int buffer[100]
)。我需要重新组织与2d数组相同的内存。我要做的是将它键入一个双指针(
int**p
),然后将指针传递给将执行重新组织的alloc函数。函数返回后,我需要语句
p[2][2]
才能工作

代码如下:

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

void alloc(int ** buf, int r, int c)
{
    int **temp;
    temp=buf;
    for(int i=0;i<r;i++)
        buf[i]=*(temp+i*c);
}
void main()
{
    int buffer[100];
    int **p=(int **)buffer;
    alloc(p, 4, 4);
    p[2][2]=10;
    printf("%d", p[2][2]);
}
我不明白问题出在哪里。alloc函数有问题吗?或者问题出在其他地方?

您无法将一维数组转换为二维数组。事实上,每个多维数组只是一个一维/线性的单元集合,编程语言创造了多维性的错觉。您可以创建相同的幻觉,即对1D数组进行抽象,使其看起来像2D(任何更高的维度)

您可以这样做:

#define ROW 10
#define COL 10

int arr[size]={1,2...}; //I am making it global, you can declare it anywhere

int& getValueFrom2DArray(int row,int col) // return type is a reference, so that you can assign
{
 if( row>= ROW || col >= COL)
  return -1; //treating -1 as sentinel value
 return array[ row*COL + col]; // convert 2D co-ordinates into 1D position
}

int main() //return type of main should be int, not void
{
   getValueFrom2DArray(2,2) = 10;
   cout<< getValueFrom2DArray(2,2)<<endl;
   return 0;
}
#定义第10行
#定义第10列
int arr[size]={1,2…}//我正在使它全球化,你可以在任何地方申报
int&getValueFrom2DArray(int行,int列)//返回类型是一个引用,因此可以指定
{
如果(行>=行|列>=列)
返回-1;//将-1视为哨兵值
返回数组[row*COL+COL];//将二维坐标转换为一维位置
}
int main()//main的返回类型应为int,而不是void
{
getValueFrom2DArray(2,2)=10;

cout让我们检查一下您的代码,了解它为什么不起作用

让我们使用一个较短的缓冲区来了解您正在做什么

假设你有:

int buffer[9];
您希望将其视为3x3 2D数组。内存使用缓冲区:

buffer
|
v
+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+
您希望创建一个
int**p
,以便:

p[0]        p[1]        [p2]
|           |           |
v           v           v
+---+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   |   |
+---+---+---+---+---+---+---+---+---+
为了实现这一点,您需要分配内存来存储
p[0]
p[1]
p[2]
。这意味着您需要:

int** p = new int*[3];
p[0] = buffer;
p[1] = buffer + 3;
p[2] = buffer + 6;
现在,
p
以及
p[0]
p[1]
p[2]
指向有效地址。您可以使用语法
p[m][n]

在我们的代码中,您刚才分配了
p
指向与
buffer
相同的位置,并使用语句

buf[i]=*(temp+i*c);
您只是将
buffer
所持有的内存用作
int*
的持有者,这不仅会破坏
buffer
中的数据,还会使指针的值变得不可预测

这是一个工作程序

#include <stdio.h>

int main()
{
   int buffer[100];
   int rows = 4;
   int cols = 10;
   int **p = new int*[rows];
   for ( int i = 0; i < rows; ++i )
   {
      p[i] = buffer + i*cols;
      printf("%p\n", p[i]);
      for ( int j = 0; j < cols; ++j )
      {
         p[i][j] = i*2 + j*3;
      }
   }
   printf("\n");

   for ( int i = 0; i < rows; ++i )
   {
      for ( int j = 0; j < cols; ++j )
      {
         printf("%d ", p[i][j]);
      }
      printf("\n");
   }
}
#包括
int main()
{
int缓冲区[100];
int行=4;
int cols=10;
int**p=新int*[行];
对于(int i=0;i
如果使用C,只需将数组强制转换为正确的类型:

void main() {
    int width = 10, height = 10;
    int buffer[width*height];
    int (*p)[width] = (int (*)[width])buffer;
    p[2][2]=10;
    printf("%d", p[2][2]);
}
或直接使用二维阵列:

void main() {
    int width = 10, height = 10;
    int buffer[width][height];
    buffer[2][2]=10;
    printf("%d", buffer[2][2]);
}
这是可行的,因为C中的2D数组是数组的数组。因此2D数组是由十个数组组成的数组,每个数组有十个元素,所有元素都顺序存储在内存中。类型
int(*)[width]
表示指向其中一个线数组的指针的类型。因此,当您执行
p[2]
,调用指针算法,在取消引用指针之前将两倍于线数组大小的指针添加到指针上。这(间接)会导致第三个线数组的第一个元素出现
int*
,您可以再次调用相同的指针算法来选择2D数组中的正确元素

<>这在C++中是不可能的,因为数组类型在C++中必须有编译时的大小。C在这方面更灵活,允许您轻松地将任意大小的2D数组传递给函数:

void foo(int width, int height, int (*image)[width]);

void main() {
    int width = 10, height = 10;
    int buffer[width][height];
    foo(width, height, buffer);
}
#包括
int main(){
int缓冲区[100];
int(*p)[4]=(int(*)[4])缓冲区;//int p[25][4]
p[2][2]=10;
printf(“%d\n”,p[2][2]);
printf(“%d\n”,缓冲区[4*2+2]);//10
返回0;
}

1d数组不会因为这样使用而变成2d。您的完整代码是错误的。您不能将1d缓冲区变成2d,您可以做的是从1d缓冲区中提取行、列并返回元素的抽象(例如方法),因此对于该方法的客户机来说,它看起来像是使用2d数组来删除
(int**)
cast您在main()中执行的操作并重新编译代码。现在看看编译器错误。这些错误的意思是他们所说的。cast不会神奇地将一种类型转换为另一种类型。问题是
p
是指向指针的指针,而不是2D数组。因此,当编译器看到
p[2][2]
,它要做的第一件事是尝试检索
p[2]
,它希望它是指向int
指针。让我们调用该指针
q
。编译器检索
q
后,它尝试检索
q[2]
,它希望是一个
int
。但是,由于
q
不是有效的指针,这会导致访问冲突。一些解释可能会更好地通过类型转换组织与2d数组相同的内存。在回答中,我的意思是。注释是二等的citisens@sph714很高兴能帮上忙。C++中有没有解决办法?@布鲁恩o、 我只知道两种方法来启用C++中运行时数组大小的
p[2][2]
索引:1)为行指针分配一个单独的数组(键入
int**
),并将它们初始化为指向2D数组中的各个行。2)编写一个2D数组类来重载
[]
运算符返回线数组指针。在这种情况下,2D数组类将在内部管理缓冲区。感谢您的回复!
void foo(int width, int height, int (*image)[width]);

void main() {
    int width = 10, height = 10;
    int buffer[width][height];
    foo(width, height, buffer);
}
#include <stdio.h>

int main(){
    int buffer[100];
    int (*p)[4]=(int (*)[4])buffer;//int p[25][4]

    p[2][2]=10;
    printf("%d\n", p[2][2]);
    printf("%d\n", buffer[4*2+2]);//10
    return 0;
}