2010-05-15 44 views

Trả lời

32

Không có biểu hiện new/delete trong C.

Tương đương gần nhất là malloc and free functions, nếu bạn bỏ qua các nhà thầu/hủy và loại an toàn.

#include <stdlib.h> 

int* p = malloc(sizeof(*p)); // int* p = new int; 
... 
free(p);      // delete p; 

int* a = malloc(12*sizeof(*a)); // int* a = new int[12]; 
... 
free(a);       // delete[] a; 
+2

* @ KennyTM: * Có 'sizeof (* p)' thực sự dereference 'p', hoặc nó hoàn toàn tương đương với viết' sizeof (int) '? Dường như trong trường hợp trước, biểu thức này có khả năng gây ra lỗi phân đoạn (vì 'p' chưa được gán vào thời điểm này). Trong trường hợp thứ hai, tôi có thể vẫn thích viết 'sizeof (int)' bởi vì có ít khả năng hiểu lầm hơn những gì phát biểu này. – stakx

+5

@stakx: Toán tử 'sizeof' được đánh giá tại thời gian biên dịch. Không có dereferencing. 'sizeof (* p)' được ưu tiên 'sizeof (int)' vì nếu bạn thay đổi kiểu 'p' thành' double' thì trình biên dịch không thể cảnh báo bạn về kích thước không khớp. – kennytm

+8

@stakx Toán tử 'sizeof' là ánh xạ từ ** type ** đến' size_t'. Giá trị ** của toán hạng của nó không thú vị chút nào. Ví dụ, trong 'sizeof (1 + 2)', hoàn toàn không cần tính kết quả '3'. Toán tử 'sizeof' đơn giản nhìn thấy biểu thức của kiểu' int + int' và cho rằng kết quả cũng là 'int'. Sau đó, nó ánh xạ 'int' thành 4 (hoặc 2 hoặc 8, tùy thuộc vào nền tảng). Đó là điều tương tự với 'sizeof (* p)'. Hệ thống kiểu biết rằng, ở mức loại, dereferencing một 'int *' tạo ra một 'int'. 'sizeof' không quan tâm đến giá trị' * p', chỉ có kiểu quan trọng. – fredoverflow

3

Không trực tiếp sao chép chính xác nhưng tương đương tương đương là không có giấy phép và miễn phí.

<data-type>* variable = (<data-type> *) malloc(memory-size); 
free(variable); 

Không constructors/destructors - C nào không có họ :)

Để có được bộ nhớ kích thước, bạn có thể sử dụng sizeof điều hành.

Nếu bạn muốn làm việc với mảng đa chiều, bạn sẽ cần phải sử dụng nó nhiều lần (như mới):

int** ptr_to_ptr = (int **) malloc(12 * sizeof(int *)); //assuming an array with length 12. 
ptr[0] = (int *) malloc(10 * sizeof(int)); //1st element is an array of 10 items 
ptr[1] = (int *) malloc(5 * sizeof(int)); //2nd element an array of 5 elements etc 
+4

Trong C bạn không cần phải truyền từ void * đến các con trỏ khác. Chỉ int * p = malloc (sizeof (int) * cElements); –

+0

Chris: Bạn có chắc chắn không? Tôi đã không làm việc với C cho một thời gian khá bây giờ, nhưng IIRC, tôi đã phải làm điều đó vì loại trả về của malloc là void *. –

+0

Trong c 'void *' tự động chuyển đổi thành các kiểu con trỏ khác. Việc đưa trở về malloc có thể gây ra lỗi nếu bạn không bao gồm 'stdlib.h', vì các tham số sẽ được giả định là' int'. –

2

Sử dụng malloc/chức năng miễn phí.

6

Lưu ý rằng các nhà thầu có thể ném ngoại lệ trong C++. Tương đương player* p = new player(); sẽ là một cái gì đó như thế này trong C.

struct player *p = malloc(sizeof *p); 
if (!p) handle_out_of_memory(); 
int err = construct_player(p); 
if (err) 
{ 
    free(p); 
    handle_constructor_error(); 
} 

tương đương với delete p là đơn giản, bởi vì hàm hủy nên không bao giờ "ném".

destruct(p); 
free(p); 
+0

Cái gì 'construct_player' trông như thế nào? –

5

Sử dụng newdelete trong C++ kết hợp hai trách nhiệm - phân bổ/giải phóng bộ nhớ động, và initialising/thả một đối tượng.

Như tất cả các câu trả lời khác đều nói, cách phổ biến nhất để cấp phát và giải phóng bộ nhớ động là gọi mallocfree. Bạn cũng có thể sử dụng các hàm dành riêng cho hệ điều hành để có được một bộ nhớ lớn và phân bổ các đối tượng của bạn trong đó, nhưng điều đó hiếm hơn - chỉ khi bạn có các yêu cầu khá cụ thể mà malloc không thỏa mãn.

Trong C, hầu hết các API sẽ cung cấp một cặp hàm đáp ứng các vai trò khác của newdelete.

Ví dụ, các tập tin api sử dụng một cặp chức năng mở và đóng:

// C++ 
fstream* fp = new fstream("c:\\test.txt", "r"); 
delete fp; 

// C 
FILE *fp=fopen("c:\\test.txt", "r"); 
fclose(fp); 

Nó có thể là fopen sử dụng malloc phân bổ lưu trữ cho FILE struct, hoặc nó có thể tĩnh phân bổ một bảng cho số lượng tệp con trỏ tối đa khi bắt đầu quá trình. Vấn đề là, API không yêu cầu khách hàng sử dụng mallocfree. Các API khác cung cấp các chức năng chỉ thực hiện khởi tạo và giải phóng một phần hợp đồng - tương đương với hàm tạo và hàm hủy, cho phép mã máy khách sử dụng bộ nhớ tự động, tĩnh hoặc động.Một ví dụ là pthreads API:

pthread_t thread; 

pthread_create(&thread, NULL, thread_function, (void*) param); 

này cho phép sự linh hoạt cho khách hàng hơn, nhưng tăng các khớp nối giữa các thư viện và khách hàng - khách hàng cần phải biết kích thước của các loại pthread_t, trong khi đó nếu thư viện xử lý cả hai phân bổ và khởi tạo máy khách không cần biết kích thước của kiểu, vì vậy việc triển khai có thể thay đổi mà không thay đổi máy khách. Không giới thiệu nhiều khớp nối giữa máy khách và thực thi như C++. (Thường thì tốt hơn khi nghĩ C++ là một ngôn ngữ lập trình meta mẫu với vtables hơn là một ngôn ngữ OO)

+0

Bạn có thể giải thích chính xác những yêu cầu cụ thể mà malloc không đáp ứng được không? – Pacerier

+0

@Pacerier 'malloc' cấp phát bộ nhớ. 'toán tử new' (thường) cấp phát bộ nhớ * và * khởi tạo bộ nhớ để chứa các giá trị được cung cấp bởi hàm tạo của lớp đối tượng được chỉ định. (có một biến 'toán tử mới' được gọi là 'vị trí mới' không phân bổ bộ nhớ, vì vậy bạn có thể sử dụng malloc cho phần đầu tiên, và mới cho thứ hai nếu bạn muốn) –

Các vấn đề liên quan