以下代码无效:
int main()
{
int n =5;
float ** p = new float[n][5]; //error: cannot initialize a variable of type
//'float **' with an rvalue of type 'float (*)[5]'
}
我预计在将新操作符应用到float[n][5]
后,将返回float**
。那么new float[n][5]
究竟会返回什么样的类型?
UPD:以下代码有效:
int main()
{
float* p[5];
float ** t = p; //OK
}
答案 0 :(得分:2)
float (*)[5]
是指向float
的数组5的指针,这是new float[n][5]
正在返回的内容。
float **p
声明指向float
指针的指针,该指针与float (*)[5]
float* p[5];
声明指向float
您可以执行以下操作:
float (*p)[5] = new float[n][5];
float **p = new float* [5];
答案 1 :(得分:1)
错误消息显示返回的类型
float (*)[5]
这是指向一个包含5个float类型元素的数组的指针。
至于float **
那么它是指向float类型对象的指针,要查看区别,请执行以下代码
float ( *p1 )[5];
float **p2;
std::cout << sizeof( *p1 ) << std::endl;
std::cout << sizeof( *p2 ) << std::endl;
这是指针算术中使用的值,例如,如果p1被初始化,那么++ p1将具有比初始地址大sizeof( *p1 )
的地址
考虑以下代码
会更清楚typedef float T1[5];
typedef float *T2;
std::cout << sizeof( T1 ) << std::endl;
std::cout << sizeof( T2 ) << std::endl;
T1 *p1 = new T1[5];
T2 *p2 = new T2[5];
答案 2 :(得分:0)
如果较低的维度确实是常数(5),那么你可以使用它:
typedef float float_arr[5];
int main()
{
int n = 5;
float_arr* p = new float_arr[n];
...
}
答案 3 :(得分:0)
取消引用数组的方式如下:
float* data = float [8];
data[5] = *(data + 5);
float* data = float [10][3];
data[7][1] = *(data + ((10 * 7) + 1));
float* data = float [2][4][6];
data[2][3][5] = *(data + ((((2 * (2 * 4)) + (3 * 4)) + 5);
etc
多维数组实现为数组,编译器指定第一个之后维度所需的额外数学。这与浮点数指针数组不同,浮点数指向浮点数。
为了进一步说明,在float** p = new float [n][5];
的情况下,分配的内存为SIZEOF(float) * n * 5
个字节,p
设置为指向该内存的指针。编译器不允许您出于正当理由分配给float**
,而不是因为它强制您遵守标准或约定或其他内容。如果您要将一个有效的一维float**
手动解除引用到一维浮点数组中,例如(例如,第三行中的第二个元素)*(*(p + (n * 2)) + 1)
,那么float
将被读作指针类型,在大多数现代系统中可能是UINT32
或UINT64
,因此在任何一种情况下float
都会被解除引用,几乎可以肯定在一个无效的位置,导致内存访问冲突,或者某个有效位置有其他数据,但肯定不是你想要的。最重要的是,在64位系统的情况下,如果数组被分配为float** p = new float [1][1];
,则可能会在第一阶段发生内存访问冲突,因为预期的64位指针会大于已分配float
,因为它们的大小通常为32位。
答案 4 :(得分:0)
试试这个
int n = 5;
typedef float * FloatPointer;
FloatPointer p [] = {new float [5],new float [5],new float [5],new float [5],new float [5],};
由于n不是const值,编译器无法在编译时分配空间。