首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 變長數組(VLA) 與動態內存分配:約瑟夫問題中棧上數組定義的編譯器差異解析

     編輯:程式設計綜合問答

代碼現場


int main() {
    int n, m;
    cin >> n >> m;
    bool str[n+1];  // ❌ VLA:變長數組,C++標準不支持
    // ...
}

編譯器行為差異

編譯器標準模式行為原因
VC++ 6.0預C++98報錯不支持VLA,嚴格遵循標準
Dev-C++ (GCC)GNU擴展編譯通過GCC默認啟用 `-std=gnu++98` 支持VLA擴展
MSVC (VS2019+)/std:c++17報錯 C2133標準禁止VLA
GCC/Clang-std=c++17報錯標準模式禁用GNU擴展
GCC/Clang-std=gnu++17通過(警告)GNU擴展模式允許VLA

三種標準合規替代方案


// 方案1:std::vector(推薦,自動管理內存)
std::vector str(n + 1, false);

// 方案2:new[] / delete[](手動管理,教學用)
bool *str = new bool[n + 1]();
delete[] str;  // 必須釋放

// 方案3:std::unique_ptr(現代C++,RAII)
auto str = std::make_unique(n + 1);

全局/靜態數組 vs 局部數組

特性全局/靜態數組局部數組(棧)動態數組(堆)
生命周期程序全周期函數調用期間手動控制
大小確定編譯期常量編譯期常量 / VLA(非標)運行期變量
內存區域.data/.bss段棧(默認1-8MB)堆(GB級)
跨函數訪問需extern聲明不可直接訪問傳遞指針/引用

約瑟夫問題優化版


#include 
#include 
#include 
using namespace std;

int main() {
    int n, m;
    if (!(cin >> n >> m)) return 0;
    
    vector eliminated(n + 1, false);  // 標準合規
    int remaining = n;
    int pos = 0, count = 0;
    
    while (remaining > 0) {
        pos = (pos % n) + 1;  // 環狀遍歷 1..n
        if (!eliminated[pos]) {
            if (++count == m) {
                eliminated[pos] = true;
                cout << pos << setw(5);
                if (--remaining) cout << endl;
                count = 0;
            }
        }
    }
    return 0;
}

總結

VLA是GCC擴展,**標準C++禁止**。VC6報錯是正確的,Dev-C++通過是寬容的。現代C++請無腦使用`std::vector`,安全、標準、無內存洩漏。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved