2010-10-31 21 views
23

Tôi đang làm việc để sửa đổi một chương trình C++ tương đối lớn, không may là có ai đó trước tôi sử dụng cú pháp C hay C++ hay không (đây là bộ phận kỹ thuật điện tại một trường đại học, và EEs luôn bị cám dỗ sử dụng C) cho mọi thứ, và thật không may trong trường hợp này, mọi người thực sự có thể thoát khỏi nó).Đối tượng C++ được tạo mới, bị hủy với miễn phí(); Tệ như thế nào?

Tuy nhiên, nếu ai đó tạo ra một đối tượng:

Packet* thePacket = new Packet();

Liệu nó quan trọng cho dù là bị phá hủy với delete thePacket; hoặc free(thePacket);?

Tôi nhận thấy rằng xóa cuộc gọi hủy trong khi miễn phí() thì không, nhưng Packet không có hàm hủy. Tôi đang có một thời gian khủng khiếp bị mắc kẹt trong một đầm lầy quản lý bộ nhớ ở đây và tôi nghĩ đây có thể là một trong nhiều vấn đề.

+4

Gói có một trình phá hủy, ngay cả khi bạn không thể nhìn thấy nó. Nó ... gah, trả lời dưới đây. – slezica

+0

Câu trả lời đúng là bạn không nên xóa mọi thứ. Bọc chúng lại. – GManNickG

Trả lời

33

Có vấn đề gì.

Đối với bộ nhớ thu được bằng cách sử dụng new bạn phải sử dụng delete.

Đối với bộ nhớ thu được bằng cách sử dụng malloc bạn phải sử dụng free.

newmalloc có thể sử dụng các cấu trúc dữ liệu khác nhau trong nội bộ để theo dõi những gì và vị trí đã phân bổ bộ nhớ. Vì vậy, để giải phóng bộ nhớ, bạn phải gọi hàm tương ứng đó biết về cấu trúc dữ liệu đó. Tuy nhiên, đó là một ý tưởng tồi để kết hợp hai loại cấp phát bộ nhớ này vào một đoạn mã.

+4

'new' và' malloc' ** có thể ** sử dụng các cấu trúc dữ liệu khác nhau trong nội bộ để theo dõi phân bổ bộ nhớ. Họ không phải làm vậy. –

+1

Cảm ơn! Chỉ là loại câu trả lời tôi đang tìm kiếm. Yaay để đi qua mã của người khác để xem những gì họ sử dụng để tạo ra những gì ... sẽ là một niềm vui. Dmitri

+0

@Dmitri Tôi nghe bạn :) và bạn được chào đón nhiều nhất. Thời gian cho grep hùng mạnh – srean

19

Nếu bạn gọi free(), trình hủy không được gọi.

Ngoài ra, có no guarantee that new and free operate on the same heap.

Bạn cũng có thể ghi đè lên newdelete để hoạt động đặc biệt trên một lớp học đặc biệt. Nếu bạn làm như vậy, nhưng hãy gọi free() thay vì tùy chỉnh delete, sau đó bạn bỏ lỡ bất kỳ hành vi đặc biệt nào mà bạn đã viết vào delete. (Nhưng bạn có thể sẽ không hỏi câu hỏi này nếu bạn đã làm điều đó, bởi vì bạn sẽ biết những hành vi nào mà bạn đã bỏ lỡ ..)

+0

Cảm ơn. Xem bình luận của tôi trên bài viết Omnifarious '(tôi đã đọc từ dưới lên) – Dmitri

+0

@Dmitri, tôi đã không đề xuất xác định lại 'xóa' như một giải pháp - tôi đã chỉ ra là một vấn đề tiềm năng khác. Tôi đã chỉnh sửa câu trả lời của mình để làm cho nó rõ ràng hơn một chút. –

+0

Nếu bạn ghi đè toàn bộ 'new' và' delete' thì bạn * có * để sử dụng 'malloc()' và 'free()'. – wilhelmtell

4

Bạn hoàn toàn đúng, chính xác là NOT. Như bạn đã nói, miễn phí sẽ không gọi hàm hủy. Ngay cả khi Packet không có một destructor rõ ràng, nó sử dụng một kế thừa.

Sử dụng free trên một đối tượng được tạo với new cũng giống như phá hủy chỉ những gì một bản sao nông sẽ đạt được. Phá hủy sâu CẦN chức năng hủy.

Ngoài ra, tôi không chắc chắn các đối tượng được tạo bằng new() trên cùng một bản đồ bộ nhớ dưới dạng bộ nhớ malloc() 'd. Họ không được đảm bảo, tôi nghĩ vậy.

5

Packet có hàm hủy, ngay cả khi bạn chưa khai báo rõ ràng. Nó có một destructor mặc định. Trình phá hủy mặc định có thể không thực sự làm được nhiều, nhưng bạn không thể tin vào trường hợp đó. Nó tùy thuộc vào trình biên dịch những gì nó làm.

newmalloc cũng có thể có các triển khai khác nhau cực kỳ khác nhau. Ví dụ, xóa luôn luôn được gọi trong một bối cảnh mà nó có thông tin hoàn hảo về kích thước của cấu trúc dữ liệu mà nó xóa lúc biên dịch. free không có sự sang trọng này. Có thể phân bổ mà new đang sử dụng có thể không lưu trữ các byte ở đầu vùng bộ nhớ cho biết số byte mà nó chiếm. Điều này sẽ dẫn đến free để làm điều hoàn toàn sai và làm hỏng chương trình của bạn khi giải phóng một cái gì đó được phân bổ với new.

Cá nhân, nếu nhận được mọi người làm điều đúng hoặc sửa chữa các mã cho mình là hoàn toàn không thể, tôi sẽ tuyên bố của riêng tôi toàn cầu operator new mà gọi malloc như vậy thì free chắc chắn sẽ không sụp đổ, mặc dù nó sẽ vẫn không gọi destructor nói chung thực sự xấu xí.

4

Tóm lại, nó cũng tệ như hành vi không xác định.

Điều này là tự giải thích.

C chuẩn ($ 7.20.3.2/2) - "The miễn phí chức năng làm cho không gian chỉ để bởi ptr được deallocated, có nghĩa là, tạo sẵn cho phân bổ thêm Nếu ptr là một con trỏ null. , không có hành động xảy ra. nếu không, nếu đối số không phù hợp với một con trỏ trước trả về bởi các calloc, malloc, hoặc chức năng realloc, hoặc nếu không gian đã được deallocated bởi một cuộc gọi để giải phóng hoặc realloc, hành vi không định nghĩa được."

1

nếu ai đó tạo ra một đối tượng:

Packet* thePacket = new Packet(); 

Liệu nó quan trọng cho dù là bị phá hủy với thePacket xóa; hoặc miễn phí (thePacket); ?

Có vấn đề gì. free (thePacket) sẽ gọi hành vi không xác định nhưng delete thePacket sẽ không và tất cả chúng ta đều biết Hành vi không xác định có thể có hậu quả tai hại.

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