无法将int *(*)[]转换为int(**)[]

时间:2016-03-29 03:28:08

标签: c++ types new-operator allocation

int main()
{
    int j;
    std::cin >> i >> j;
    int (**ptr)[1];
    ptr = new (int*[i][1]);//error
    for (int index = 0;index < i;++index)
        ptr[index] = new (int[j][1]);
}

我有编译错误。

然后,我该如何分配int(**)[]

4 个答案:

答案 0 :(得分:2)

问题。

原始代码,除了我添加了缺少的#include指令 - 为避免错误猜测您的代码,以及正在讨论的无关问题,请在发布的代码中包含所有:< / p>

#include <iostream>
int main()
{
    int j;
    std::cin >> i >> j;
    int (**ptr)[1];
    ptr = new (int*[i][1]);//error
    for (int index = 0;index < i;++index)
        ptr[index] = new (int[j][1]);
}

使用MinGW g ++ 5.1.0进行编译:

C:\my\forums\so\116> g++ --version | find "++"
g++ (tdm64-1) 5.1.0

C:\my\forums\so\116> g++ original.cpp
original.cpp: In function 'int main()':
original.cpp:5:17: error: 'i' was not declared in this scope
     std::cin >> i >> j;
                 ^
original.cpp:9:35: error: ISO C++ forbids variable length array [-Wvla]
         ptr[index] = new (int[j][1]);
                                   ^
original.cpp:9:36: error: non-constant array new length must be specified without parentheses around the type-id [-Wvla]
         ptr[index] = new (int[j][1]);
                                    ^

C:\my\forums\so\116> _

该编译器检测到以下问题:

  • 缺少变量i的声明。

  • 由于语法错误,无意中使用了C99 可变长度数组,VLA。

使用Visual C ++ 2015更新2进行编译:

C:\my\forums\so\116> cl /nologo- 2>&1 | find "++"
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23725 for x86

C:\my\forums\so\116> cl original.cpp
original.cpp
original.cpp(5): error C2065: 'i': undeclared identifier
original.cpp(7): error C2065: 'i': undeclared identifier
original.cpp(7): error C2440: '=': cannot convert from 'int *(*)[1]' to 'int (**)[1]'
original.cpp(7): note: Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
original.cpp(8): error C2065: 'i': undeclared identifier

C:\my\forums\so\116> _

此编译器不支持C99 VLA,因此诊断

  • 指针赋值中的不兼容类型。

显然这是OP关注的错误信息,但OP报告为

  

无法将int )[]转换为int(**)[]

这是没有意义的,因为人们确实可以在数据指针类型之间进行转换。

所以,

  • 问题中的错误说明不正确。

  • 除了由OP挑出的错误之外,代码还存在问题(缺少包含,缺少变量声明)。

  • 目前还不清楚代码的用途是什么,除非是一个非常抽象的意义,允许使用诸如“使用std::vector”之类的建议。

但是,代码段

for (int index = 0;index < i;++index)
    ptr[index] = new (int[j][1]);

强烈暗示 这是尝试执行int值的动态大小矩阵(2D数组),其中维度由用户指定,并且我假设在下面。

修复原始代码。

通常有助于为事物命名。在这种情况下,为清楚起见,我们可以将int*类型命名为Int_array_ptr。这表明了预期的用法:不是作为指向单个int的指针,而是作为指向int数组的第一项的指针,即作为指向数组的指针。

#include <iostream>
int main()
{
    int n_rows;
    int n_columns;
    std::cin >> n_rows >> n_columns;

    using Int_array_ptr = int*;
    Int_array_ptr* matrix;
    matrix = new Int_array_ptr[n_rows];     // An array of `n_rows` pointers.
    for( int i = 0; i < n_rows; ++i )
    {
        matrix[i] = new int[n_columns]();   // The `()` adds zero-initialization.
    }

    // At this point one can use it like `matrix[row][column] = 42`.
}

生成的结构称为锯齿状数组,因为它允许列向量具有不同的长度(这里它们的长度都相同)。

如何做一般的矩阵。

矩阵作为锯齿状阵列的一个很好的替代方案是使用单个连续的1D阵列作为存储,并且只为该阵列提供2D索引。

管理阵列存储的一个好方法是使用std::vector

将索引操作和其他数组内容(或大多数相关操作集合在一个公共状态)封装的好方法是定义一个类。

因此,强烈建议定义一个类,该类在单个1D阵列上提供2D索引操作,其存储由std::vector管理。

索引理想情况下是通过operator[],但作为成员操作,它只能接受1个参数。写一下这有点麻烦,例如matrix[Location(3,58)]而不是理想的matrix[3,58](将被解析为使用逗号表达式)。因此,通常使用operator()函数调用运算符代替[]

可以改为支持符号matrix[3][58],但让我们选择概念上更简单的operator()实现:

#include <iostream>
#include <vector>
#include <stdlib.h>     // EXIT_FAILURE
using namespace std;

class Matrix
{
private:
    vector<int>     items_;
    int             n_columns_;

    auto index_of( int const row, int const col ) const
        -> int
    { return row*n_columns_ + col; }

public:
    auto operator()( int const row, int const col )
        -> int&
    { return items_[index_of( row, col )]; }

    auto operator()( int const row, int const col ) const
        -> int
    { return items_[index_of( row, col )]; }

    Matrix( int const n_rows, int const n_columns )
        : items_( n_rows*n_columns )
        , n_columns_( n_columns )
    {}
};

auto main() -> int
{
    int n_rows;
    int n_columns;
    std::cin >> n_rows >> n_columns;
    if( cin.fail() ) { return EXIT_FAILURE; }

    Matrix matrix( n_rows, n_columns );
    // At this point one can use it like `matrix( row, column ) = 42`.
}

这远远超过原始代码,但是

  • 它是可重复使用的代码,可以节省工作量,

  • 它是更强大的代码,自动化困难的事情(内存管理),

  • 它甚至可以更高效,因为它通过单一动态分配进行管理。

答案 1 :(得分:0)

你已经分配了一个指针数组,然后每个元素(指针)都指向一个像

这样的数组
string strInsert = @"Insert into INFOR_STUDENT(IdStudent, NameStudent, NameClass, IdClass, BirthStudent, SexStudent) VALUES (:IdStudent, :NameStudent, :NameClass, Select IdClass from Infor_Class where NameClass = :NameClass, :BirthStudent, :SexStudent)";

修改

回到您的代码

将类型E定义为int [1];

int i = 20, j = 40;

int** ptr = new int*[i];

for (int a = 0; a < i; a++) {
    ptr[a] = new int[j];
    // ...
    delete [] ptr[a];
}
delete [] ptr;

所以只是一个指向整数指针的指针,不像你说的那样

答案 2 :(得分:0)

好像你想要分配二维数组。所以分配应该如下:

int i, j;       // Initialize some value to i, j.
....
int **ptr = new int*[i];
for(int k = 0; k < i; k++) {
    ptr[k] = new int[j];
}   

这将生成一个包含i行和j列的二维数组。

答案 3 :(得分:0)

您正在尝试分配int (*)[1]个对象的数组。您已经注意到像new int(*)[1]这样的语法不起作用,因为它被解析为new int后跟函数调用运算符,因此您必须使用new(T)表单。

此外,int *[i][1]不正确,因为int *是指向int的指针。就像你在int (**ptr)[1]中所做的那样,你必须使用括号来打破*中的int

因此的正确语法是 new( int (*[i])[1] )。但不幸的是,new(T)表单不允许在括号内包含非常量表达式!

技术信息:案例sizeof(T)alignof(T),{{1}有专门的语法(C ++ 14 [dcl.name] / 1) }和new(T)和演员;它只允许方括号为空或在方括号内包含常量表达式typeid(T)案例([expr.new] / 1)有另一个单独的语法(它知道new T但不知道[],并且允许非常量表达式),并且两者都有这些与在其他情况下解析声明符的语法是分开的。

所以解决这个问题的唯一方法是(同时保留()的类型)是使用typedef:

ptr

每一行都是:

typedef int Arr1[1];
ptr = new Arr1 *[i];