2009-04-10 44 views
47

Tôi đã sử dụng C++ trong một vài năm và hôm nay tôi đã thấy một số mã, nhưng làm thế nào điều này có thể hoàn toàn hợp pháp?Kích thước mảng tại thời gian chạy mà không có phân bổ động được cho phép?

int main(int argc, char **argv) 
{ 
    size_t size; 
    cin >> size; 
    int array[size]; 
    for(size_t i = 0; i < size; i++) 
    { 
     array[i] = i; 
     cout << i << endl; 
    } 

    return 0; 
} 

Được biên soạn theo GCC.

Kích thước có thể được xác định tại thời gian chạy như thế nào mà không cần new hoặc malloc?

Chỉ cần kiểm tra kỹ, tôi đã googled một số và tất cả các mã tương tự của tôi được xác nhận là cung cấp lỗi kích thước bộ nhớ.

Ngay cả chương trình C++ của Chương trình Làm thế nào để p. 261 trạng thái theo Lỗi lập trình chung 4.5:

Chỉ có thể sử dụng các hằng số để khai báo kích thước mảng tự động và tĩnh.

Làm sáng tỏ tôi.

+2

lưu ý rằng DMA có nghĩa là "truy cập bộ nhớ trực tiếp" - Tôi nghĩ bạn đang hỏi về phân bổ động –

+2

C hoặc C++? Chọn một_. –

+1

Một lần nữa, chọn một: C hoặc C++. Câu hỏi này là một cách rõ ràng và chỉ về C; không nên có một thẻ C++. –

Trả lời

49

Điều này hợp lệ trong C99.

Chuẩn C99 hỗ trợ các mảng có kích thước biến trên ngăn xếp. Có lẽ trình biên dịch của bạn cũng đã chọn để hỗ trợ cấu trúc này.

Lưu ý rằng điều này khác với mallocnew. gcc phân bổ mảng trên ngăn xếp, giống như nó với int array[100] bằng cách chỉ cần điều chỉnh con trỏ ngăn xếp. Không có phân bổ đống nào được thực hiện. Nó khá giống với _alloca.

+7

Tôi đã xem kịch bản tương tự này trong một tệp trong cơ sở mã của chúng tôi đã được viết cách đây vài tháng.Tôi đã bối rối, cũng như phần còn lại của nhóm, về lý do tại sao nó được biên soạn. Trong tình huống của chúng ta, kích thước của mảng được tính toán trước khi khai báo mảng đó (cũng không nên cho phép mảng đó?) Dù sao thì, một thử thách đã xảy ra. Bất cứ ai có thể trả lời lý do tại sao điều này là hợp pháp được một tart pop. Nếu bạn ở Seattle, hãy cho tôi biết. Tôi có một tart pop cho bạn. –

+0

Bạn có thể cung cấp một số thông tin/liên kết về cách ngăn xếp nội bộ hoạt động trong trường hợp này không? Điều này có giới thiệu một số chi phí trong thời gian chạy không? – balki

+1

@balki Chi phí là nhỏ, vì nó cơ bản tăng/giảm con trỏ ngăn xếp. Hành vi ngăn xếp có thể cơ bản giống với trường hợp bình thường nếu bạn lưu con trỏ ngăn xếp ban đầu ở đầu hàm. –

7

Chỉ là valid chỉ trong C99. Lần tới, bạn có thể thử kiểm tra mã của mình theo số reliable compiler.

4

Đây là C99 hợp lệ, C++ không hợp lệ. Đây là một trong số ít sự khác biệt giữa hai ngôn ngữ.

+2

Tôi đoán nó sẽ được hỗ trợ trong C++ 0x –

+0

Không theo mục 8.3.4 của tiêu chuẩn dự thảo. –

+2

nó sẽ không bao giờ được bao gồm trong c + + 1x: D nhưng chúng ta hãy hy vọng dynarray được in Tôi rất thích nó. vì vậy bạn có thể làm dynarray a (some_size); và có nó phân bổ hiệu quả, có thể với trình biên dịch hax như _alloca và như vậy. –

18

Điều này được gọi là VLAs (mảng độ dài biến đổi). Nó là tiêu chuẩn trong c99, nhưng gcc cho phép nó trong mã C++ như một phần mở rộng. Nếu bạn muốn từ chối mã, hãy thử thử nghiệm với các tùy chọn -std=standard, -ansi-pedantic.

0

Bạn có thể cung cấp kích thước cho một mảng động trong nếu bạn đang sử dụng trình biên dịch Dev-Cpp tôi đã thử nó và không có lỗi nhưng trên C++ thị giác và trình biên dịch trực quan là không thể. Tôi cho rằng lý do là dev-C++ gán một số dương cho số int không được khởi tạo và khi chúng ta cho nó một số, nó sẽ được thay thế bằng một số đã cho. nhưng có lẽ các trình biên dịch khác cung cấp null cho các biến chưa được khởi tạo.

+0

Hầu hết các trình biên dịch không gán bất kỳ thứ gì cho các biến cục bộ chưa được khởi tạo, chúng thường sẽ xuất hiện để giữ bất kỳ thứ gì trong bộ nhớ mà chúng chiếm giữ cho đến khi chúng được chương trình gán. Dường như Dev-C++ bạn tham chiếu là một IDE trên đầu trang của MinGW, bao gồm một cổng GCC như trình biên dịch. Như đã lưu ý trong các câu trả lời khác, VLAs không phải là chuẩn C++, nhưng một số trình biên dịch (bao gồm cả g ++) vẫn hỗ trợ chúng. – jerry

+0

Dev-C++ không phải là trình biên dịch. Không phải là Visual Studio. Dev-C++ sử dụng GCC/G ++ làm trình biên dịch của nó, trong khi Visual Studio sử dụng cl (trình biên dịch ngược của Microsoft). Bản thân họ, Dev-C++ và Visual Studio là môi trường phát triển tích hợp (IDE). Đây là một sự khác biệt quan trọng để thực hiện. Dev-C++ không "gán" bất cứ thứ gì. Trình biên dịch thực hiện điều đó. – Elkvis

-1

Mảng độ dài biến đổi (VLAs) được hỗ trợ trong tiêu chuẩn C++ 14, gần đây đã được chấp nhận và đang chờ xuất bản.

+1

VLAs vẫn không phải là một phần của tiêu chuẩn. Có một [dynarray] (http://en.cppreference.com/w/cpp/container/dynarray) TS, nhưng vẫn chưa được phê chuẩn. – Jason

0

Mã này chạy trong trình biên dịch GNU GCC.

#include<bits/stdc++.h> 

int main(int argc, char **argv) 

{ 
    size_t size; 

    std:: cin >> size; 

    int array[size]; 

    for(size_t i = 0; i < size; i++) 

{ 

array[i] = i; 

     std:: cout << i; 

} 

    return 0; 
} 
Các vấn đề liên quan