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(**)[]
?
答案 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];