2009-12-28 30 views
5

Tôi thường lập trình trong c + +, nhưng đang sử dụng một số hàm clibrary cho char * của tôi. Một số trang con người thích 'getline', nói rằng đầu vào phải là một mảng được tạo khối.là có một sự khác biệt giữa mảng malloced và mảng mới

OK, để sử dụng 'mới' thay thế?

Tôi có thể thấy cho mẫu nhỏ của tôi rằng nó hoạt động, nhưng điều này có thể tại một số điểm kết quả trong một số hành vi không xác định lạ?

Tôi biết rằng 'mới' phải khớp với 'xóa' và 'quảng cáo' với 'miễn phí'.

Tôi cũng không sử dụng std :: string. Và điều này là cố ý.

Cảm ơn

+0

Không có điều gì không ổn. Nhưng nếu bạn đang sử dụng C + + tại sao không sử dụng std :: getline()? –

+2

Bất cứ khi nào bạn thấy một cái gì đó như thế này trong tài liệu, bạn cần đào sâu hơn và tìm hiểu xem họ có gợi ý một con trỏ 'malloced' hay không vì chúng đang sử dụng thuật ngữ C hoặc vì hàm này được gọi là realloc() hoặc free(). Các câu trả lời bình chọn cao nhất dưới đây cho rằng câu trả lời trước đây mặc dù tôi tin rằng chức năng mà bạn đang đề cập đến phải thực hiện với chức năng thứ hai như Martin đã chỉ ra. Bạn không nên ghép cặp malloc/miễn phí và mới/xóa không chính xác, vì vậy tốt nhất bạn nên thực hiện nghiên cứu bổ sung về các chức năng cụ thể mà bạn đang gọi khi điều này xuất hiện. –

Trả lời

13

Bộ đệm được chuyển tới đường nối() PHẢI được gắn cố định.

Lý do là getline() có thể gọi realloc() trên bộ đệm nếu cần thêm dung lượng.

realloc() như free() chỉ nên được sử dụng với bộ nhớ được phân bổ bởi malloc().Điều này là do malloc() và mới cấp phát bộ nhớ từ các khu vực lưu trữ khác nhau:

Xem:. What is the difference between new/delete and malloc/free?

sử dụng cơ bản mới "The 'Free Store' khi malloc sử dụng 'The Heap' Cả hai khu vực là một phần của "Heap ứng dụng" (Mặc dù tiêu chuẩn không thực sự yêu cầu một đống ứng dụng vì đó là một chi tiết triển khai thực hiện) Mặc dù chúng đều nằm trong "Heap ứng dụng" nhưng các khu vực này không cần chồng chéo.

Trang người dùng cho getline():

Thông báo dòng này:

Ngoài ra, trước khi gọi getline(), * lineptr có thể chứa một con trỏ đến một malloc() - phân bổ đệm * n byte trong kích thước . Nếu bộ đệm không đủ lớn để giữ dòng, getline() thay đổi kích thước nó bằng realloc(), update * lineptr và * n khi cần thiết.

+2

@Martin: bạn đang trỏ đến một chức năng mở rộng GCC "getline". Tôi không nghĩ rằng nó quá tuyệt vời để khuyên bạn nên sử dụng chức năng này không cầm tay, đặc biệt là cho người mới –

+1

@Eli: câu hỏi đặc biệt đề cập đến 'getline'. –

+0

@Eli: Tôi khuyên bạn nên chống lại bất kỳ chức năng C nào có thể sử dụng C++ thay thế. Nhưng câu hỏi đặt ra là hỏi cụ thể về hàm getline() của C. Và khi các tài liệu hướng dẫn cụ thể đề cập đến sử dụng bộ nhớ malloc (ed) thường có một lý do rất tốt để làm như vậy. –

2

Có, đó là OK để sử dụng một con trỏ giao new khi một "malloced" được mong muốn.

Bằng cách này, getline không phải là ISO C. Có một số getline trong thư viện chuẩn C++, nhưng thư viện đó dự kiến ​​là std::string. Để đọc tệp C chuẩn, bạn nên sử dụng fgets. Các công trình sau đây (mã đơn giản giả định sự tồn tại của infile và không kiểm tra fgets giá trị trả về - mà có lẽ bạn nên trong mã thực):

// infile is some open FILE* object 
int mylen = 100; 
char* line = new char[mylen]; 
fgets(line, mylen, infile) 

Tuy nhiên, một sự từ bỏ bắt buộc: nó tốt hơn nhiều để sử dụng std::stringgetline nếu bạn đang sử dụng C++.

+1

Tôi biết tiêu chuẩn C ban đầu xuất phát từ ANSI nhưng đó là cơ quan quốc gia và ISO hiện chịu trách nhiệm về tiêu chuẩn. Vui lòng thử sử dụng "ISO C" nếu bạn có thể. – paxdiablo

+1

@paxdiablo: được sửa thành "ISO C". sử dụng ANSI chỉ là một thói quen từ thời gian qua :-) –

+5

Nó không phải là luôn luôn ok để sử dụng bộ nhớ mới (ed), nơi malloc (ed) dự kiến. Nếu nó chỉ sử dụng bộ nhớ như là bộ nhớ thô tốt. Nhưng nếu thói quen quản lý bộ nhớ được sử dụng trên con trỏ thì bạn không thể đưa ra giả định này. getline() có thể có khả năng gọi realloc() trên con trỏ được truyền. Điều này tương đương với việc gọi free() trên con trỏ tức là nó là hành vi không xác định. –

1

Hoàn toàn tốt đẹp khi có một mảng 'mới' thay vì mảng 'malloc'ed cho mục đích.

Sự khác biệt giữa hai là (liệt kê một số trong số họ):

  • new/delete gọi constructor/destructor của các đối tượng liên quan đến không giống như malloc/free. Sau này không thể thực hiện khởi tạo/deinitialisation chất liệu.
  • lợi nhuận mới một con trỏ kiểu thích hợp nhưng con trỏ gì lợi nhuận malloc phải được typecasted (C++)
  • mới/xóa không có thay thế realloc không giống như mới/xóa

Những điều này sẽ không tạo ra nhiều sự khác biệt trong chương trình của bạn; như đã nêu ở trên, hoàn toàn tốt đẹp để đi đến 'mới'

Mã của bạn sẽ không thành công, trừ khi mới hoặc malloc không thành công, trong trường hợp đó, 'mới' sẽ ném ngoại lệ, và malloc trả về con trỏ NULL.

EDIT: Với mục đích, mảng phải là 'malloc'ed. Tôi đoán là tôi đã sai rồi! Cảm ơn Martin! :)

+0

@Srivatsan Iyer: Đọc này để biết thêm sự khác biệt: http://stackoverflow.com/questions/240212/what-is-the-difference-between-new-delete-and-malloc-free –

+0

Cảm ơn! Trên thực tế tôi chỉ cố gắng để đưa vào * một số * của các điểm; không phải hầu hết trong số họ! : P – SuperSaiyan

+6

__FAIL__: Điều này là không chính xác các dòng PHẢI được malloced. Xem bên dưới. –

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