我正在尝试在我的C ++代码中使用memset。但是,代码在我的机器上无法正常工作。
OS:-MacOS 10.12
G ++:-g ++-4.9(自制GCC 4.9.4_1)4.9.4
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
int test;
cin >> test;
while(test--){
int size = 1e5+10;
int arr[size];
memset(arr,0,sizeof(arr));
int cnt = 0;
for(ll i = 0; i < size; i++){
if(arr[i]==0) cnt++;
}
cout << cnt << endl;
}
return 0;
}
命令1:-
g++ -std=c++14 file.cpp
然后是./a.out
我得到了输出
96835
有警告
file.cpp: In function 'int main()':
file.cpp:17:32: warning: taking sizeof array of runtime bound [-Wvla]
memset(arr,0,sizeof(arr));
命令2:-
g++ -std=c++11 file.cpp
然后是./a.out
我得到了输出
100010
如您所见,2是正确的,1是不正确的。这种意外行为的原因可能是什么?
答案 0 :(得分:5)
您的程序格式错误。数组的大小必须是编译时间常数,您可以使用非常数变量。
您正在使用GCC,它允许将可变长度数组作为C ++的语言扩展。该功能类似于C99中标准的可变长度数组,不过正如AnT在a comment中指出的那样,C ++扩展名不同于标准C VLA。
但是,过去曾经有人提议将“具有自动存储持续时间的运行时大小的数组”添加到C ++标准中。该提议与GCC的扩展不同之处在于,运行时大小的数组的sizeof
格式不正确(差异不必局限于此)。在将该提案从标准草案中撤回之前,GCC 4.9以实验性C ++ 14模式实施了该提案。
因此,您的程序在所有不带VLA的正式C ++标准版本中格式不正确,但在具有VLA的GNU扩展C ++中格式正确,但在GCC 4.9实现的实验标准中又格式不正确具有运行时大小的数组,但没有sizeof
。
由于数组的大小是常量,因此只需声明变量常量即可使程序格式正确:
const int size = 1e5+10;
现在,不使用运行时大小的数组。
答案 1 :(得分:1)
原因是因为C ++不支持VLA(可变长度数组)。某些编译器仍然支持它们,因为它们已经具有C99的代码。
但是由于未为C ++定义,因此获得的是随机的。例如,sizeof
可能不是C ++中的函数调用。在C99中,它适用于VLA。但是在C ++中可能不是。这意味着它将返回一个固定数字,可能与您期望的不完全相同。