2010-11-03 57 views
8

Tôi đang sử dụng STL string trong một ứng dụng của tôi, và gần đây tôi đã thử nghiệm nó cho rò rỉ bộ nhớ, và tôi nhận thấy rằng rất nhiều chuỗi của tôi không được giải quyết đúng vào cuối chương trình.Rò rỉ bộ nhớ chuỗi C/C++?

Tôi đã thử nghiệm đoạn mã sau (không đúng nguyên văn) với một trong những chuỗi:

const string* cppString = &obj->objString; 
const char* cString = cppString->c_str(); 
delete obj; 

Sau đó, tôi đặt một break-point và nhận thấy rằng, trong khi string rằng cppString chỉ để không còn tồn tại, cString vẫn đang trỏ đến một chuỗi kiểu C, chắc chắn đủ, là một trong số đó không thể được deallocated ở cuối.

Tôi có thiếu thứ gì đó về cách chuỗi C/C++ hoạt động không? Làm thế nào tôi có thể nhận được đại diện C của chuỗi được deallocated là tốt?

EDIT: Một số thông tin khác. Lớp học obj của tôi thuộc loại Dialog, được kế thừa Popup. Tôi nghĩ rằng có thể là vậy, vì khi tôi xóa obj, tôi coi nó là Popup*, nhưng tôi đã thử nó trong một chương trình riêng biệt nhỏ và xóa dưới dạng lớp cha mẹ xóa đúng các biến thành viên con (có ý nghĩa , tất nhiên).

Tôi đã sử dụng dấu vết rò rỉ bộ nhớ trong VS và nó cho thấy chuỗi đã bị rò rỉ là chuỗi được tạo khi tôi tạo Dialog và đặt objString thành chuỗi được chuyển làm tham chiếu đến hàm tạo.

Cảm ơn,
Jengerer

+0

(Rất tiếc, nhận xét trước đó của tôi bị lỗi khi đọc ưu tiên người vận hành). Tôi nghĩ bạn cần hiển thị thêm mã. Nếu không thấy định nghĩa 'obj' và cách phân bổ của nó, thật khó để suy đoán liệu' obj-> objString' có được giải phóng một cách chính xác hay không. –

+0

Dường như một mớ hỗn độn ở đây, vì vậy tôi sẽ cập nhật OP với nhận xét của tôi. – Jengerer

+1

Liệu 'Popup' có một destructor ảo? –

Trả lời

8

Những gì bạn đang nhìn thấy là không xác định hành vi -đó là không thực sự là một rò rỉ bộ nhớ. Bộ nhớ cho chuỗi C được deallocated (ít nhất là như xa như bạn đang quan tâm), nhưng dữ liệu vẫn còn có thể truy cập về mặt kỹ thuật. Khi bạn deallocate bộ nhớ, bộ nhớ thường không bị xóa, do đó, dữ liệu có thường xuyên ở lại miễn là bộ nhớ không được tái sử dụng bởi một phân bổ tiếp theo.

Đọc dữ liệu sau khi được phân phối là hành vi không xác định: bạn có thể nhận dữ liệu trước khi được phân phối, bạn có thể nhận dữ liệu rác, có thể làm hỏng chương trình hoặc thậm chí bạn có thể xóa ổ cứng của mình rất có khả năng).

Vì vậy, miễn là đối tượng std::string đang được xử lý đúng cách, thì mọi bộ nhớ được sử dụng cho biểu diễn chuỗi C của nó cũng sẽ được deallocated. Bạn không cần phải lo lắng về điều đó.


EDIT: Thực ra nó quay ra đối tượng của bạn đã không nhận được fulled bị phá hủy vì tầng lớp phụ huynh Popup không có một destructor ảo. Kết quả là, hàm hủy cho lớp con Dialog không được gọi, vì vậy hàm hủy cho phiên bản std::string không được gọi.

+0

Điều đó có ý nghĩa, nhưng tôi đã sử dụng thủ tục phát hiện rò rỉ bộ nhớ của Visual Studio (về cơ bản là sau tất cả các cuộc gọi 'malloc' và' free') và khi tôi xóa thông tin rò rỉ bộ nhớ ở cuối chương trình, chuỗi đó, những vị trí tương tự, được hiển thị là không được xử lý đúng cách. – Jengerer

3

Sự cố rất có thể không nằm trong số std::string, nhưng trong obj (bất kể loại nào). Lưu ý rằng bạn đã xóa obj, chứ không phải cppString.Tôi đoán là obj không lưu trữ objString trong một lớp con trỏ thông minh cũng không xóa objString trong destructor của nó, và do đó bạn có rò rỉ đó.

+0

'objString' là một chuỗi thông thường, không phải là một con trỏ, vì vậy nó sẽ tự động bị xóa bởi destructor mặc định, không? – Jengerer

+0

@Jengerer, bạn được chỉ định từ objString để nhập "const string *", không nhập "const string", do đó, nó phải là loại con trỏ, trừ khi bạn đã chia sẻ mã khác với chúng tôi. –

+0

những gì tôi có nghĩa là trong lớp đối tượng, 'objString' là một loại' chuỗi' và không phải là một con trỏ. Khi tôi gán nó cho 'const string *', tôi đã làm '& obj-> objString', vì vậy tôi đã sử dụng toán tử & để lấy địa chỉ. – Jengerer