2009-07-30 24 views

Trả lời

12

Về mặt kỹ thuật, đây không phải là một phần của C++. Bạn có thể làm các mảng chiều dài thay đổi trong C99 (ISO/IEC 9899: 1999) nhưng chúng không phải là một phần của C++. Như bạn đã phát hiện, chúng được hỗ trợ như một phần mở rộng của một số trình biên dịch.

10

G ++ hỗ trợ tính năng C99 cho phép các mảng có kích thước động. Nó không phải là tiêu chuẩn C++. G ++ có tùy chọn -ansi tắt một số tính năng không có trong C++, nhưng đây không phải là một trong số chúng. Để làm cho G ++ từ chối mã mà, sử dụng -pedantic tùy chọn:

 
$ g++ -pedantic junk.cpp 
junk.cpp: In function ‘int main()’: 
junk.cpp:4: error: ISO C++ forbids variable-size array ‘pz’ 
6

Nếu bạn muốn có một mảng động trên stack:

void dynArray(int x) 
{ 
    int *array = (int *)alloca(sizeof(*array)*x); 

    // blah blah blah.. 
} 
+6

Nó hoạt động, nhưng tôi muốn thêm trích dẫn sau đây từ "man alloca": "Hàm alloca() là máy và trình biên dịch phụ thuộc, việc sử dụng nó không được khuyến khích." –

2

Thực tế mà nói, nếu bạn muốn thực hiện một mảng động bạn nên sử dụng std :: vector, như trong:

 
#include <iostream> 
#include <cstdlib> 
#include <vector> 

int main(int argc, char* argv[]) 
{ 
    int size; 
    std::cin>>size; 
    std::vector<int> array(size); 
    // do stuff with array ... 
    return 0; 
} 

Nếu bạn chỉ là tò mò về cú pháp, sau đó những gì bạn đang tìm kiếm là:

 
//... 
int* array = new int[size]; 
// Do stuff with array ... 
delete [] array; 
//... 

Cả hai loại này đều không được phân bổ với bộ nhớ cục bộ. Mảng có kích thước động được phân bổ tự động bằng bộ nhớ cục bộ hiện không được hỗ trợ trong C++ chuẩn, nhưng được hỗ trợ trong tiêu chuẩn C hiện tại.

+0

Không phân bổ bộ nhớ mới trên heap? Tôi đã được ấn tượng rằng OP muốn nó được phân bổ trên stack, được đưa ra tiêu đề của câu hỏi. – mrduclaw

+1

không thay đổi thực tế rằng vector là giải pháp đúng. Trong trường hợp này, anh ta không thể có những gì anh ta yêu cầu. Vector là gần nhất. (Và không, tôi không xem xét alloca trong bối cảnh C++) – jalf

+1

Đối với các ứng dụng cần hiệu năng quan trọng trong một số trường hợp, alloca là câu trả lời đúng nếu trình biên dịch không hỗ trợ cú pháp "int array [x]". Phân bổ dựa trên ngăn xếp, thường chỉ là một lệnh trừ đi từ con trỏ ngăn xếp, là cách nhanh hơn so với các đối tác heap. –

13

Dưới đây là câu trả lời của bạn kết hợp của tất cả những cái khác:

Mã của bạn ngay bây giờ là không chuẩn C++. Nó tiêu chuẩn C99. Điều này là do C99 cho phép bạn khai báo các mảng động theo cách đó. Để làm rõ, đây cũng là tiêu chuẩn C99:

#include <stdio.h> 

int main() 
{ 
    int x = 0; 

    scanf("%d", &x); 

    char pz[x]; 
} 

Đây là không tiêu chuẩn bất cứ điều gì:

#include <iostream> 

int main() 
{ 
    int x = 0; 
    std::cin >> x; 
    char pz[x]; 
} 

Nó không thể được tiêu chuẩn C++ vì đòi hỏi kích thước mảng liên tục, và nó không thể là tiêu chuẩn C vì C không có std::cin (hoặc không gian tên, hoặc các lớp học, vv ...)

Để làm cho nó chuẩn C++, làm điều này:

int main() 
{ 
    const int x = 12; // x is 12 now and forever... 
    char pz[x]; // ...therefore it can be used here 
} 

Nếu bạn muốn có một mảng động, bạn thể làm điều này:

#include <iostream> 

int main() 
{ 
    int x = 0; 
    std::cin >> x; 

    char *pz = new char[x]; 

    delete [] pz; 
} 

Nhưng bạn nên làm điều này:

#include <iostream> 
#include <vector> 

int main() 
{ 
    int x = 0; 
    std::cin >> x; 

    std::vector<char> pz(x); 
} 
3

Phân bổ mảng với chiều dài biến trên stack là tốt ý tưởng, bởi vì nó nhanh và không phân mảnh bộ nhớ. Nhưng C++ Standard tiếc là không hỗ trợ nó. Bạn có thể thực hiện việc này bằng cách sử dụng trình bao bọc mẫu cho hàm alloca. Nhưng việc sử dụng alloca không thực sự là sự phù hợp tiêu chuẩn.

Cách tiêu chuẩn là sử dụng tiêu chuẩn :: vector với phân bổ tùy chỉnh nếu bạn muốn tránh phân mảnh bộ nhớ và phân bổ bộ nhớ tăng tốc. Hãy xem boost::pool_alloc để có mẫu phân phối nhanh.