为什么float **不能用float(*)[5]初始化?

时间:2014-07-26 18:50:52

标签: c++ arrays

以下代码无效:

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]'
}

demo

我预计在将新操作符应用到float[n][5]后,将返回float**。那么new float[n][5]究竟会返回什么样的类型?

UPD:以下代码有效:

int main()
{
    float* p[5];
    float ** t = p; //OK
}

demo

5 个答案:

答案 0 :(得分:2)

float (*)[5]是指向float的数组5的指针,这是new float[n][5]正在返回的内容。

float **p声明指向float指针的指针,该指针与float (*)[5]

不同

float* p[5];声明指向float

的指针数组5

您可以执行以下操作:

  • 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将被读作指针类型,在大多数现代系统中可能是UINT32UINT64,因此在任何一种情况下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值,编译器无法在编译时分配空间。