我正在尝试以下代码:
int main() {
int x[10] ;
int a[] = {1,2,3,4,5} ;
int n ;
int b[n] ;
//int c[] ; gives compilation error
cout<<sizeof(x)<<endl ; //prints 40
cout<<sizeof(a)<<endl ; //prints 20
cout<<sizeof(b)<<endl ; //prints 4
}
现在我的问题是当我定义b
时到底发生了什么。
我试图阅读类似问题的答案,但我没有得到满意的答复。
因为数组是静态创建的,所以在声明它们时必须给出大小。那么为什么b
的声明有效。 sizeof(b)
是否表明这被视为int pointer
答案 0 :(得分:5)
究竟发生了什么
int n ; int b[n] ;
使用未初始化整数的值(窄字符类型除外)具有未定义的行为( UB )。此外,由于n
不是编译时常量,而是用作数组的大小,因此程序根据C ++标准格式不正确(这意味着允许编译器拒绝编译程序) ,并且至少需要显示诊断信息。
但是,如果你的编译器支持可变长度数组( VLA ,一种语言扩展),那么究竟会发生什么取决于编译器如何实现VLA(当然,如何应对你介绍的UB。
那么为什么
b
的声明有效。
实际上, 在标准C ++中无效。
sizeof(b)
是否表明这只被视为int
指针
没有。由于行为未定义,因此输出不显示任何内容。即使你的系统上int
指针的大小恰好是4,输出恰好也是偶然的。
答案 1 :(得分:2)
在C ++中,不允许使用可变长度数组,数组必须是固定大小的,如果要动态分配大小,可能需要使用malloc
并手动分配内存。但是,int
的默认值可用于此处。我不会推荐这种做法,因为它可能会产生未定义的行为。阅读这些链接Array[n] vs Array[10] - Initializing array with variable vs real number和Why aren't variable-length arrays part of the C++ standard?他们有一些很好的解释。
答案 2 :(得分:0)
首先,int b[n]
不是有效的C ++代码,除非n
是常量表达式。你只是因为使用GCC而逃脱它,并且允许它作为扩展名(https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html#Variable-Length)。
其次,为了检查发生了什么,让我们看看:
我的程序var-arr.cpp:
#include <iostream>
using namespace std;
int main() {
int m=0, n=5, k;
int a[m], b[n], c[k];
cout
<< "sizeof(a)=" << sizeof(a)
<< " sizeof(b)=" << sizeof(b)
<< " sizeof(c)=" << sizeof(c)
<< endl;
}
以下是我编译并运行它时会发生的事情([~/CPP]
是提示符)
[~/CPP] g++ -o var-arr var-arr.cpp
[~/CPP] ./var-arr
sizeof(a)=0 sizeof(b)=20 sizeof(c)=0
一段时间之后
[~/CPP] ./var-arr
Segmentation fault (core dumped)
这是什么意思?这意味着当您在函数中编写int n;
时,n
仍然未初始化。所以当你在它之后写int a[n];
时,a
的长度可以是任意的。它也可能太大而无法分配a
。