我有几个与数组相关的问题。我已经研究过,数组大小必须是常量的,声明/编译器必须知道它的值。但是使用GNU GCC编译器(C ++ 11标准过滤器)并且我能够使用变量作为数组大小完美地编译和运行程序,在动态声明所述数组时(使用new
)
int num;
cout << "How big an array? ";
cin >> num;
int *arr = new int [num];
问题1)这被认为是标准吗?我的教授是矛盾的。
Ques2)如果是标准,那么在这种情况下,是否可以在创建后扩展数组(或任何数组)的大小?
Ques3)同样,如果这个表达式是标准的,那么是否可以在函数中使用它 - 例如。使用函数创建这样的数组? (如果是这样,怎么样?)
(PS:嗨,我是新来的,也是C ++的新手)
答案 0 :(得分:6)
问题1)这被认为是标准吗?我的教授是矛盾的。
是的,这完全有效。请注意,您需要使用operator arr
显式删除delete[]
指向的内存。使用std::vector<int>
会更好,它将为您执行内存管理。
您可能会误认为C++
中不允许使用可变长度数组(VLA):
// same num as the one in your example
int arr[num]; // ERROR
这在C
中有效,但在C++
中无效(C ++ 14将包含VLA,尽管它们与C
VLA有一些差异。)
问题2)如果它是标准的,在这种情况下,是否可以扩展 创建后数组(或任何数组)的大小?
不,你不能扩展它。您可以分配更大的数组,复制元素并删除前一个元素。同样,如果您使用的是std::vector<int>
,则会自动完成。
Ques3)同样,如果这个表达式是标准的,那么它是否可能 在函数中使用它 - 例如。使用函数来创建这样的 阵列? (如果是这样,怎么样?)
是的,当然:
int *allocate(size_t size) {
return new int[size];
}
但是再次使用std::vector
:
int num;
cout << "How big an array? ";
cin >> num;
std::vector<int> arr(num); // num elements, all of them initialized to 0
// insert 42 at the end. reallocations(if any) are done automatically
arr.push_back(42);
答案 1 :(得分:3)
我已经研究过,数组大小必须在声明/编译器必须知道它的值时保持不变。
嗯,这是真的,但仅适用于静态或自动数组。您正在堆上分配动态数组,这是不同的。
在全局范围内声明的数组必须具有常量大小。
int arr[5];
在函数中自动分配的数组必须具有常量大小(例外情况见下文)。
void f() {
int arr[5];
}
在new
堆上分配的动态数组可以包含任何大小,常量或变量。
new int[5];
new int[n * 4];
例外情况是GCC允许使用变量来声明自动数组的大小:
void f(int n) {
int arr[n];
}
但是,这种用法并不标准。
答案 2 :(得分:0)
<强>载体强>
(同意动态调整大小的矢量):
std::vector<int> v;
v.push_back(1);
v.push_back(1);
v.resize(v.size()+10, 5); // Greater resized
v.resize(v.size()-1); // Lower resized
<强>阵列强>
旁注:(关于堆栈和堆分配)
处理array
的方式会导致显着不同的结果(请参阅此非常有趣的discussion):
// Create 500 bytes on the heap
char *pBuffer = new char[500]; // or malloc in C
// Create 500 bytes on the stack
char buffer[500];
答案 3 :(得分:0)
问题1 - 运算符'new'用于进行动态分配,我的意思是,当你以前不知道数组的大小是什么时,那么,没有问题,你可以做到!我认为你的教授们对C sintax感到困惑,因为新的既不存在也不允许做类似的事情:int p [n];例如。
问题2 - 不,不可能增加使用operator new创建的数组的大小。您必须分配另一个数组并复制数据。您可以考虑使用向量以便轻松完成。
问题3 - 我不明白为什么这样做,但有可能......
int* createarray(int size)
{
return new int[size];
}
int main()
{
int *p = createarray(10);
}
答案 4 :(得分:0)
Q1:这是标准吗?
鉴于定义int n = 42,new float [n] [5] 形式良好(因为n是a的表达式) noptr-new-declarator),但是新的float [5] [n]是不正确的(因为n是 不是一个恒定的表达)。 - 5.3.4.6,N3242
如果分配的类型是数组类型,则为分配函数 name是operator new [],deallocation函数的名称是 operator delete []。
- 5.3.4.8,N3242
new T[5]
致电operator new[](sizeof(T)*5+x)
这里,x和y是表示数组分配开销的非负非特定值;
- 5.3.4.12,N3242
Q2:如果是标准的话,在这种情况下,是否可以在创建后扩展数组(或任何数组)的大小?
部分否,或不推荐。
当分配函数返回null以外的值时,它必须是指向存储块的指针
其中保留了对象的空间。大多数分配发生在堆中,并且可能没有更多连续内存,这对于数组很重要。
如果您必须执行此操作并进行内存轮询,请使用placement new运算符,您可以部分执行此操作,但您现在所做的是分配器的设计者所做的事情,并且存在破坏内部存储器存储的风险。
问题3:使用函数创建这样的数组? (如果是这样,怎么样?)
new-expression创建的实体具有动态存储持续时间 (3.7.4)。 [注意:这种实体的生命周期不一定 仅限于创建它的范围。 - 结束说明] - 5.3.4.1,N3242
其余的事情是如何设计这样的功能以满足您的需求,甚至使用模板。
1 template<typename T>T* foo(std::size_t size){
2 return new T[size] ;
3 }