2013-06-10 38 views
5

Tôi đang bị rò rỉ bộ nhớ trong một chương trình lớn hơn và tôi tin rằng đây là nguyên nhân của nó.con trỏ char là bộ nhớ mảng cấu trúc bị rò rỉ

#include <stdlib.h> 
#include <Windows.h> 

typedef struct _struct{ 
    char* name; 
} str; 

int main() { 
    system("PAUSE"); 

    str* Character = (str*)malloc(sizeof(str) * 20000); 

    for(int i = 0; i < 20000; i++){ 
     Character[i].name = (char*)malloc(20000); // Assign memory. 
    } 

    for(int i = 0; i < 20000; i++){ 
     free(Character[i].name);   // Free memory. 
    } 

    free(Character); 
    system("PAUSE"); 
} 

Bộ nhớ lúc tạm dừng đầu tiên: ~ 500K.

Bộ nhớ ở giây tạm dừng: ~ 1.7M.

Sử dụng VS2012 để thử nghiệm. Bất kỳ ý tưởng?

+1

Mã của bạn có vẻ chính xác. Bạn đo mức sử dụng bộ nhớ như thế nào? Có thể quản lý heap của bạn chỉ đơn giản là đã không nén heap của nó sau cuộc gọi của bạn để 'miễn phí'? Trong trường hợp này, bộ nhớ bổ sung sẽ được gán cho quy trình của bạn nhưng sẽ không được chương trình của bạn sử dụng để thực sự có sẵn cho mã khác để phân bổ. – simonc

+0

Khi u sử dụng malloc, hãy chắc chắn để kiểm tra xem bộ nhớ thực sự được phân bổ nếu (Character == NULL) – hazzelnuttie

+0

bạn không nên đúc sự trở lại từ malloc. Đây là C và bạn có thể gán một khoảng trống * cho bất kỳ thứ gì. –

Trả lời

4

Bạn đo lường số lượng bộ nhớ bị chương trình chiếm đóng như thế nào? Một điều trên đỉnh đầu của tôi là bạn đang nhìn vào kích thước của bộ làm việc mà hệ điều hành đang theo dõi. Vì bạn đã phân bổ và giải phóng rất nhiều bộ nhớ, kích thước của bộ đó đã tăng lên. Một số hệ điều hành sẽ điều chỉnh kích thước của bộ làm việc sau một thời gian, một số sẽ không. Chúng ta đang xem hệ điều hành gì?

+0

Windows 7 Ultimate và sử dụng bộ nhớ từ Task Manager – Marc

+0

Tôi không chắc chính xác Windows đang làm gì (sẽ kiểm tra sau này, hoặc ai đó có thể điền vào), nhưng có lẽ nó không hiển thị những gì bạn mong đợi. Các hệ điều hành hiện đại quản lý bộ nhớ xử lý theo cách tổng thể và lười biếng để tiết kiệm xử lý và có thể trì hoãn việc deallocation của các trang. Việc thực hiện malloc và miễn phí có thể được đặt trước bộ nhớ quá. Nếu bạn thực sự muốn chắc chắn, hãy sử dụng một công cụ như valgrind để kiểm tra rò rỉ. – idoby

+0

Tôi chỉ chạy nó với DrMemory và nó tìm thấy 3 (1536 byte) rò rỉ có thể với 319 phân bổ vẫn có thể truy cập. – Marc

3

Khi bạn gọi malloc, bộ nhớ được cấp phát trên heap. Nếu không có đủ dung lượng trống trên heap, chương trình sẽ yêu cầu hệ điều hành để có thêm bộ nhớ và một đoạn khác được mua lại. Bộ nhớ thu được từ hệ điều hành thường không được trả lại cho đến khi chương trình kết thúc (mặc dù điều này tùy thuộc vào hệ điều hành).

Không thể sử dụng kích thước chương trình một cách bình thường để kiểm tra rò rỉ bộ nhớ! Sử dụng Valgrind hoặc một công cụ tương tự để kiểm tra bộ nhớ không bao giờ bị free d.

-1

str * Ký tự = (str *) malloc (sizeof (str) * 20000);

Trong dòng trên, bạn đang cấp phát bộ nhớ bằng cách tìm kích thước của cấu trúc. Ở đây kích thước của cấu trúc bạn sẽ nhận được sẽ là kích thước của chiều rộng con trỏ và không phải là kích thước của char.

giả sử ví dụ nếu chiều rộng con trỏ là 32 bit, nó sẽ phân bổ (4 * 20000) = 80000 byte.

Nếu bạn muốn phân bổ cho của 20000 struct,

str * Character = (str *) malloc (sizeof (char) * 20000);

+1

str * Ký tự là một mảng cấu trúc, không phải ký tự (tên khó hiểu tôi có thể đồng ý) vì vậy sizeof (str) là chính xác –

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