2017-04-22 119 views
-3

在下面的代码中,我发现读取一定数量的输入后,N的值将被替换(为0)。我相信这是因为我已经在堆栈中分配了K和S阵列。我想知道我的结论是否正确?我很久以前用C语言编写代码并切换到python和其他脚本语言。所以,我的记忆管理似乎已经抛弃了。堆栈上的值损坏

ofstream cop("op1.txt"); 
ifstream cinp("in1.txt", ios::binary); 
int T, t=1; 
cinp >> T; 
for(;t <= T;t++){ 
    fflush(stdin); 
    long D; 
    int N; 
    long K[N], S[N]; 
    cinp >> D >> N; 
    double times[N], max = 0; 
    cout << D << " " << N << endl; 
    for(long i=0; i<N; i++) { 
     cout << D << " " << N << endl; // Output of this line is shown below till N gets replaced by 0 
     cinp >> K[i] >> S[i]; 
     times[i] = (1.0 * (D - K[i]))/S[i]; 
     if(max < times[i]) 
      max = times[i]; 
    } 
    cout << D << " " << N << endl; 
    if(t == 3) { 
     cout << D << " " << N << endl; 
     for(int i=0;i<N;i++) 
      cout << K[i] << " " << S[i] << endl; 
    } 
    cop << "Case #" << t << ": " << std::setprecision(6) << std::fixed << D/max << endl; 
} 

,当它被替换

912786011 100 <--- Needs to read 100 nos as N is 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 100 
912786011 0 <---------------- Became 0 

而且一瞥,我想知道如果我的结论是对的又是什么,可以在栈上分配的内存良好的数额(不包括新)?

+0

如果在编译时未知N,则不能声明'long K [N]'。更糟的是,即使你可以在运行时分配它,你甚至不会在分配数组之前读入'N'! – CoryKramer

+0

变长数组在C++中是非法的(你可能使用了一些编译器扩展),所以你应该把它们分配在堆上。 – VTT

+0

我们假设它是有效的C++,它仍然是未定义的行为,因为在使用之前N尚未被赋值。 – DeiDei

回答

0

DeiDei说得对,你错误地使用了GCC的VLA扩展。

https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html

阵列的长度被计算一次时,存储被分配 并记住该阵列的情况下,在范围你的sizeof访问它 。

所以你必须指定(并确保它的一切手段)在你声明数组之前用于大小的变量是正确的值。你没有和你走出数组边界,读取堆栈中的数据。如果这是一个功能,最有可能你会从函数退出引发运行时错误。

可变长度是用词不当种类对于这一特征,因为所以它的使用是相当有限的结果数组不能改变大小。最好使用std :: vector,您可以使用提供的大小保留构造。 VLA在C99中是允许的,但在C++中不是标准的,它们不能移植到其他C++编译器。

+0

Swift这将是一件好事,如果你可以添加矢量在堆栈上,而不是被内存和编译器处理内存的用户绑定。 – suraj

+0

矢量使用动态内存。 std :: array _may_如果足够小,则使用堆栈内存 – Swift