Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用2D C样式数组崩溃_C++_C_Arrays_Multidimensional Array - Fatal编程技术网

C++ 使用2D C样式数组崩溃

C++ 使用2D C样式数组崩溃,c++,c,arrays,multidimensional-array,C++,C,Arrays,Multidimensional Array,二维C样式阵列的常见问题。此程序可编译,但在调用Print()函数时崩溃: #include <iostream> using namespace std; static const int sx = 5, sy = 3; static double M[sy][sx] = { { 0.0, 1.0, 2.0, 3.0, 4.0 }, { 0.1, 1.1, 2.1, 3.1, 4.1 },

二维C样式阵列的常见问题。此程序可编译,但在调用
Print()
函数时崩溃:

#include <iostream>
using namespace std;

static const int sx = 5, sy = 3;
static double M[sy][sx] = { { 0.0, 1.0, 2.0, 3.0, 4.0 },
                            { 0.1, 1.1, 2.1, 3.1, 4.1 },
                            { 0.2, 1.2, 2.2, 3.2, 4.2 } };

void Print(double **M, int j, int i)
{
    cerr << M[j][i] << endl;
}

int main()
{
    cerr << M[2][3] << endl;             // Prints 3.2
    Print((double**)&M[0][0], 2, 3);     // Crash
}
#包括
使用名称空间std;
静态常数intsx=5,sy=3;
静态双M[sy][sx]={{0.0,1.0,2.0,3.0,4.0},
{ 0.1, 1.1, 2.1, 3.1, 4.1 },
{ 0.2, 1.2, 2.2, 3.2, 4.2 } };
无效打印(双**M,整数j,整数i)
{

cerr问题是
&M[0][0]
不是
双精度**
,它只是指向双精度(
double*
)的指针。 您需要将函数原型更改为
typedef double my_array_type[3][5];

无效打印(我的数组类型*M,int j,int i)
问题在于
&M[0][0]
不是
双精度**
,它只是指向双精度(
双精度*
)的指针。 您需要将函数原型更改为
typedef double my_array_type[3][5];
无效打印(我的数组类型*M,整数j,整数i)

数组不是动态的

是否可以在不更改Print()签名的情况下使其工作

不,不可能同时满足这两个要求。除非您可以将该2D阵列复制到另一个动态阵列

二维双精度数组不是指向行的指针数组。就内存而言,多维数组是扁平的。
M[0][0]
的类型是
double
,因此
&M[0][0]
的类型是
*double

请参阅有关使用数组的内容。请注意“多维数组”一章

你可能想做的事情可以这样做:

void Print(double *M, int j, int i, int width) {
    cerr << M[i + width * j] << endl;
}

Print(&M[0][0], 2, 3, sx);
void打印(双*M,整数j,整数i,整数宽度){
瑟尔
数组不是动态的

是否可以在不更改Print()签名的情况下使其工作

不,不可能同时满足这两个要求。除非您可以将该2D阵列复制到另一个动态阵列

二维双精度数组不是指向行的指针数组。就内存而言,多维数组是扁平的。
M[0][0]
的类型是
double
,因此
&M[0][0]
的类型是
*double

请参阅有关使用数组的内容。请注意“多维数组”一章

你可能想做的事情可以这样做:

void Print(double *M, int j, int i, int width) {
    cerr << M[i + width * j] << endl;
}

Print(&M[0][0], 2, 3, sx);
void打印(双*M,整数j,整数i,整数宽度){

cerr可以使
Print
函数工作,但需要更改分配数组的方式。具体来说,需要指向每行第一个元素的指针向量,并将其作为参数传递

以下是您可以如何做到这一点:

#include <iostream>
#include <cstdlib>
using namespace std;

static const int sx = 5, sy = 3;
static double M[sy][sx] = { { 0.0, 1.0, 2.0, 3.0, 4.0 },
                            { 0.1, 1.1, 2.1, 3.1, 4.1 },
                            { 0.2, 1.2, 2.2, 3.2, 4.2 } };

double **twoD(int nr, int nc) {
// function that allocates a 2D matrix and returns the result
// as a vector of pointers to the first element of each row
  double **p;
  int ii;
  p = (double**)malloc(nr * sizeof(double*));
  p[0] = (double*)malloc(nr * nc * sizeof(double));
  for(ii=1; ii<nr; ii++) {
    p[ii] = p[0] + ii * nc;
  }
  return p;
}

void free2d(double **p) {
  free(p[0]);
  free(p);
}

void Print(double **M, int j, int i)
{
    cerr << M[j][i] << " ";
}

int main()
{
    double **P;
    P = twoD(sy, sx);
    memcpy(P[0], M, sx * sy * sizeof(double));
    cerr << M[2][3] << endl;             // Prints 3.2
    int ii,jj;
    for(ii=0; ii<sy; ii++) {
      for(jj=0; jj<sx; jj++) {
        Print(P, ii, jj);
      }
      cerr << endl;
    }
    free2d(P);
}
#包括
#包括
使用名称空间std;
静态常数intsx=5,sy=3;
静态双M[sy][sx]={{0.0,1.0,2.0,3.0,4.0},
{ 0.1, 1.1, 2.1, 3.1, 4.1 },
{ 0.2, 1.2, 2.2, 3.2, 4.2 } };
双**twoD(整数编号,整数编号){
//函数,用于分配2D矩阵并返回结果
//作为指向每行第一个元素的指针向量
双**p;
int ii;
p=(双**)malloc(nr*sizeof(双*);
p[0]=(双*)malloc(nr*nc*sizeof(双));

对于(ii=1;ii可以使
Print
函数工作,但需要更改分配数组的方式。具体来说,需要指向每行第一个元素的指针向量,并将其作为参数传递

以下是您可以如何做到这一点:

#include <iostream>
#include <cstdlib>
using namespace std;

static const int sx = 5, sy = 3;
static double M[sy][sx] = { { 0.0, 1.0, 2.0, 3.0, 4.0 },
                            { 0.1, 1.1, 2.1, 3.1, 4.1 },
                            { 0.2, 1.2, 2.2, 3.2, 4.2 } };

double **twoD(int nr, int nc) {
// function that allocates a 2D matrix and returns the result
// as a vector of pointers to the first element of each row
  double **p;
  int ii;
  p = (double**)malloc(nr * sizeof(double*));
  p[0] = (double*)malloc(nr * nc * sizeof(double));
  for(ii=1; ii<nr; ii++) {
    p[ii] = p[0] + ii * nc;
  }
  return p;
}

void free2d(double **p) {
  free(p[0]);
  free(p);
}

void Print(double **M, int j, int i)
{
    cerr << M[j][i] << " ";
}

int main()
{
    double **P;
    P = twoD(sy, sx);
    memcpy(P[0], M, sx * sy * sizeof(double));
    cerr << M[2][3] << endl;             // Prints 3.2
    int ii,jj;
    for(ii=0; ii<sy; ii++) {
      for(jj=0; jj<sx; jj++) {
        Print(P, ii, jj);
      }
      cerr << endl;
    }
    free2d(P);
}
#包括
#包括
使用名称空间std;
静态常数intsx=5,sy=3;
静态双M[sy][sx]={{0.0,1.0,2.0,3.0,4.0},
{ 0.1, 1.1, 2.1, 3.1, 4.1 },
{ 0.2, 1.2, 2.2, 3.2, 4.2 } };
双**twoD(整数编号,整数编号){
//函数,用于分配2D矩阵并返回结果
//作为指向每行第一个元素的指针向量
双**p;
int ii;
p=(双**)malloc(nr*sizeof(双*);
p[0]=(双*)malloc(nr*nc*sizeof(双));
对于(ii=1;ii此:

double**
完全不同,将其或其中的任何内容强制转换为这种类型是不正确的。如果您使用的是固定阵列(如果需要,可以称之为2D阵列),则可以使用模板创建符合要求的打印功能:

template<size_t X>
void Print(double M[X], int i) {
    cerr << M[i] << endl;
}

 Print<sx>(M[2], 3);
#include <iostream>
using namespace std;

static const int sx = 5, sy = 3;
static double M[sy][sx] = { { 0.0, 1.0, 2.0, 3.0, 4.0 },
                            { 0.1, 1.1, 2.1, 3.1, 4.1 },
                            { 0.2, 1.2, 2.2, 3.2, 4.2 } };


template<int M>
void Print( double(*ar)[M] , int j, int i )
{
    std::cout << ar[j][i] << '\n';
}

int main()
{
    Print(M, 2, 3);
    return 0;
}
#包括
使用名称空间std;
静态常数intsx=5,sy=3;
静态双M[sy][sx]={{0.0,1.0,2.0,3.0,4.0},
{ 0.1, 1.1, 2.1, 3.1, 4.1 },
{ 0.2, 1.2, 2.2, 3.2, 4.2 } };
样板
无效打印(双(*ar)[M],整数j,整数i)
{
标准::cout这:

double**
完全不同,将其或其中的任何内容强制转换为这种类型是不正确的。如果您使用的是固定阵列(如果需要,可以称之为2D阵列),则可以使用模板创建符合要求的打印功能:

template<size_t X>
void Print(double M[X], int i) {
    cerr << M[i] << endl;
}

 Print<sx>(M[2], 3);
#include <iostream>
using namespace std;

static const int sx = 5, sy = 3;
static double M[sy][sx] = { { 0.0, 1.0, 2.0, 3.0, 4.0 },
                            { 0.1, 1.1, 2.1, 3.1, 4.1 },
                            { 0.2, 1.2, 2.2, 3.2, 4.2 } };


template<int M>
void Print( double(*ar)[M] , int j, int i )
{
    std::cout << ar[j][i] << '\n';
}

int main()
{
    Print(M, 2, 3);
    return 0;
}
#包括
使用名称空间std;
静态常数intsx=5,sy=3;
静态双M[sy][sx]={{0.0,1.0,2.0,3.0,4.0},
{ 0.1, 1.1, 2.1, 3.1, 4.1 },
{ 0.2, 1.2, 2.2, 3.2, 4.2 } };
样板
无效打印(双(*ar)[M],整数j,整数i)
{

std::cout数组和指针是不同的类型。在某些情况下,数组会隐式转换(衰减)为指向其第一个元素的指针,例如在本例中,当数组传递给
打印函数时

以下声明

static double M[sy][sx] = { { 0.0, 1.0, 2.0, 3.0, 4.0 },
                            { 0.1, 1.1, 2.1, 3.1, 4.1 },
                            { 0.2, 1.2, 2.2, 3.2, 4.2 } };
M
定义为
sy
的数组,即
3
元素,其中每个元素的类型为
double[5]
,即
5
double的数组。因此,在
print
函数调用中

Print((double**)&M[0][0], 2, 3);
&M[0][0]
计算为
M[0][0]
的地址,该地址的类型为
(double*)
将此值强制转换为
(double**)
是错误的,因为此地址处的值是
double
,而不是指向