C++ 使用2D C样式数组崩溃
二维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 },
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
,而不是指向