Công cụ bảo vệ mã nguồn .NET mạnh nhất, không thể unpack, miễn phí cho các khách hàng đầu tiên đăng ký.
Trang 1 trên tổng số 5 123... Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 48 kết quả

Đề tài: Bản chất của việc cấp phát bộ nhớ động và giải phóng bộ nhớ

  1. #1
    Ngày gia nhập
    06 2007
    Nơi ở
    C:\WINDOWS\system32\dllcache\
    Bài viết
    3,007

    Mặc định Bản chất của việc cấp phát bộ nhớ động và giải phóng bộ nhớ

    Hum nay mình sẽ đưa ra phân tích rõ bản chất của việc cấp phát và giải phóng bộ nhớ

    1. Dẫn nhập
    Bộ nhớ là 1 tài nguyên quan trọng trong hệ thống , được phân phối điều phối phức tạp.

    ở đây, chúng ta sẽ xét tương quan như sau cho dễ hiểu : đất là 1 tài nguyên quý giá trong thành phố và được điều phối bởi sở tài nguyên môi trường
    (coi như thế, giờ hình như nó thuộc sở nhà đất thì phải,nói tóm lại là
    sở quản lí)


    2. Cấp phát bộ nhớ :
    Bộ nhớ quan trọng như thế ko thể tùy tiện sử dụng , vì trong máy có nhiều tiếng trình cần bộ nhớ, tùy tiện sử dụng thì lấy đâu ra mà dùng ????

    ai cũng cần có đất, cứ tùy tiện lấy gì cần gì sở quản lý, như thế sẽ có người không có đất mà dùng ???



    Cấp phát bộ nhớ hoạt động như thế nào : bản chất là trao quyền sử dụng.

    hôm nay 1 người (1 con trỏ) xin cấp phát (malloc, new) 1 vùng đất, anh ta được trao quyền sử dụng 1 vùng đất đó.
    Khi này :
    + Có thể trên mảnh đất này đang trống rỗng (toàn null) nhưng cũng có thể trên đó đầy cỏ rác,hoa màu hoặc nhà cửa do người trước đó sử dụng vẫn còn . (điều này đối với anh ta mà nói nó hoàn toàn là ngẫu nhiên, ko ai có thể khẳng định được cả)
    >>>>> khi ta xin cấp phát xong thì vùng nhớ đó hoàn toàn có giá trị ngẫu nhiên


    + Nếu như khi anh ta xin cấp phát mà có đút lót để ra thêm điều kiện hoặc trước đó anh ta có thuê thêm 1 người quét dọn xây sửa thì anh sẽ có được 1 mảnh đất có sẵn cái anh ta muốn
    >>>> khi ta cấp phát đi cùng với ép buộc sẽ được vùng nhớ có giá trị như ta mong muốn
    ví dụ
    PHP Code:
    int *a=new int(4);
    int *b=(int*)malloc(1000);
    memset(b.....);
    static 
    int x[1000];
    static 
    int y[10]={1,2,3,4,5,6}; 
    <<<<<<<< toàn bộ điều này là đáp án tại sao khi cấp phát bộ nhớ lại có giá trị ngẫu nhiên



    3. Giải phóng bộ nhớ như thế nào

    Anh ta dùng xong đất rồi, ko cần nữa, đem trả quyền sử dụng mảnh đất lại cho khổ chủ.

    Giải bộ nhớ hoạt động như thế nào : bản chất là trả lại quyền sử dụng
    khi này :
    + sở sẽ thu lại quyền sử dụng đất của anh, thế là đủ rồi, sở ko cần phải động chạm sửa chữa lại gì vùng đất đó. Nên khi đó dù vùng đất đó đã được giải phóng nhưng mà hoa màu của a ta trên đó thì vẫn còn, ko có biến mất được

    điều này giải thích tại sao khi mà trong 1 số hệ điều hành đời cổ, (các bạn lính mới bây giờ chắc không gặp) nhiều bạn thử giải phóng bộ nhớ rồi, delete rồi, free rồi mà khi in thử ra vẫn thấy kết quả như thế .
    đơn giản thôi, a ta trả lại mảnh đất đó, nhưng chưa có ai thuê nó cả, chưa có ai sử dụng nên hôm sau ra xem thử thì nó vẫn như hôm trước khi a ta trả lại
    Các bạn đọc rõ chú ý ở dưới rồi hẵng hỏi thêm về câu này nhé.

    Và các bạn phải chú ý là quyền sử dụng đất mới là cái được quan tâm duy nhất của vấn đề này

    PHP Code:
    int *a=new int[10];
    int *b=(int*)malloc(1000); 
    thì giá trị trong a và b là địa chỉ của vùng nhớ được cấp phát. địa chỉ này sẽ được lưu lại trong sở, sở sẽ dùng cái số địa chỉ này để hiểu là quyền sử dụng đất khi giải phóng

    tiếp theo
    PHP Code:
    free(b);
    delete []a
    2 câu lệnh này ko có làm thay đổi giá trị của a và ba và b vẫn trỏ vào mảnh đất đấy. ok ? Và càng ko can thiệp vào vùng nhớ mà a ,b trỏ đến, cái duy nhất mà nó làm là xác nhận vùng nhớ đó đã được trả lại, đang rảnh rỗi, có thể cho thuê tiếp.

    <<< điều này giải thích cho cách hiểu sai lầm của 1 số bạn mới học đối với việc cấp phát và giải phóng



    4. Memory leak

    Câu hỏi mở rộng :
    như thế này có phải là giải phóng ko
    PHP Code:
        int*x=new int[20];
        
    x=NULL;  <<<<< như thế này có phải là giải phóng ko 
    ở trong C (not java, java khác) thì :
    câu trả lời là không , bạn đã hiểu sai lầm hoàn toàn về việc giải phóng rồi, bạn nên đọc kĩ lại phần giải phóng để hiểu tại sao.
    như thế này chính là :
    anh ta đánh mất cái quyền sử dụng đất của mình, kết quả là vùng đất đó ko được sở lấy về, sau nhiều lần như thế thì tài nguyên đất của sở càng ngày càng ít đi, hiện tượng này gọi mà memory leak


    Sau khi chương trình kết thúc , việc bộ nhớ xin cấp phát có được tự giải phóng hay ko thì tùy thuộc vào cài đặt của trình biên dịch và hệ điều hành. Chúng ta có 2 khả năng
    · Khả năng 1 : trong phần khởi động (trước khi vào function main() ), program xin một khối memory cuả system gọi là XXXX và mỗi lần malloc được gọi thì cấp pháp một phần memory cuả XXXX cho malloc. Do đó, khi program exit thì trả XXXX về cho system là xong. Trong trường hợp này không bị mất memory
    · Khả năng 2 : mỗi lần malloc được gọi thì xin memory từ system . Trường hợp này có thể memory không trả về cho system. Lúc này chương trình sẽ bị gọi là có memory leak.Như vậy sau vài lần chạy sẽ ko còn memory để cấp phát nữa


    Đó là giải thích tại sao có nhiều chương trình chạy xong, thoát ra rồi, f5 mấy lần rồi mà máy vẫn cứ ì ì ì ra..........


    5. Trên đây là cách lý thuyết cơ bản dành cho các bạn mới học, nó được áp dụng đối với lập trình trên console, (cấp sở tài nguyên thôi)
    trong windows nó cũng như thế thôi nhưng mà nó có thêm nhiều quy tắc rằng buộc chặt chẽ hơn rất nhiều (cấp bộ tài nguyên và môi trường, phải khác chứ)

    Muốn biết thêm về bộ nhớ thì xem chap 1 của tut dưới đây :
    Portable Executable File Format




    Update 9/9/10
    Câu hỏi
    Nhân tiện cho em hỏi, nếu mình khai báo 1 mảng có thể có rất nhiều phần tử thì bộ nhớ của nó sẽ được lấy từ đâu ra (Ổ cứng, Ram.... Hay là một cái gì đó mà em không biết :P). Khi em khai báo 1 mảng int a[1000000] thì nó báo là "Array size too large". Mới có 1000000 phần tử nó đã coi là lớn thì những bài toán thực tế vài triệu phần tử liền thì phải làm thế nào? hix
    Trả lời
    int a[1000000] ; khai báo ở đâu ?
    em khai báo ở sở (tức là khai báo dạng local, trong các hàm )thì sở nó xin vùng nhớ ở stack segment, mà stack segment thì đây (trong ảnh, nhỏ gọn thế này, liệu nó có cho em vùng lớn thế kia ko 1000000*4byte)
    Click vào ảnh để xem hình đẩy đủ


    đối với các bài toán cần nhiều vùng nhớ 1 cách kinh khủng thì ta thường dùng các hàm api về malloc để lấy các vùng nhớ ở free store được bộ (os-hệ điều hành) cấp phát,

    và 1 điều ko kém phần quan trọng đó là ta nên xây dựng những giải thuật thật thông minh chứ ko phải là load tràn hết lên bộ nhớ
    ví dụ xây dựng trước các phương pháp xử lý các sự kiện có thể xảy ra
    giả sử như này, tôi có 1 khối thông tin, để bắt sự kiện "tìm nhân viên mới vào công ti", tôi lập ra 1 temponary, mỗi khi chèn thằng mới vào khối thông tin của tôi, tôi gán thằng temponary này bằng với nhân viên mới, như thế tôi đã có 1 phương pháp sử lí sự kiện tốt rồi đúng ko ???


    Update 10/9/10
    câu hỏi

    Cấp phát động thì nó lấy bộ nhớ từ đâu vậy cà.
    "data segment"
    Là cái gì thế em dịch là dữ liệu phân đoạn, nghĩa là sao đây, anh langman bận rộn thế :P:P

    a. theo giáo trình đại học FPT về OS,theo giáo trình thầy phạm văn ất về tổ thức bộ nhớ, khi tiến trình chạy , bộ nhớ được mô hình thành 4 phần như sau


    (trên thực tế, trong windows, môi trường ảo hóa cụ thể này thì có cách tổ chức phức tạp hơn phát triển từ lý thuyết này)
    b. đang bận ôn thi ko có time online được


    Update 20/11/10
    Câu hỏi của quyết 1991 : sự khác nhau giữa malloc và new?


    new và malloc khác nhau cực cực kì nhiều đó các pạn à
    sơ bộ như sau, chưa phân tích kĩ
    malloc là hàm, cấp phát trả về kiểu void *, malloc thì ko gọi hàm tạo
    free ko gọi hàm hủy
    malloc trả về NULL nếu thất bại

    new là toán tử, new gọi hàm tạo, new có thể được đa năng hóa (nạp chồng),
    new ném ra exception nếu thất bại
    toán tử new và toán tử new[] ko có khả năng realloc



    Update tiếp câu hỏi hay 2/3/2010
    Trích dẫn Nguyên bản được gửi bởi first_pace Xem bài viết
    Anh cho em hỏi rõ hơn về đoạn này. Khi giải phóng rồi mà a và b vẫn trỏ đến mảnh đất đó thì nghĩa là nó vẫn có quyền kiểm soát khu vực đó, như vậy thì sao biết là khi đó đất là available đựoc ạ. Em có test một đoạn chương trình như sau.
    C Code:
    1. #include <iostream>
    2. using namespace std;
    3.  
    4. int main(){
    5.     int *p;
    6.    
    7.     p= new int[2]; // xin chính quyền cấp hai khu đất
    8.     p[0]=8888; // khu này trồng rau
    9.     p[1]=9999; // khu này nuôi lợn
    10.     cout << p[0] << "  " << p[1] << endl; // xem tình hình ruộng rau và chuồng lợn
    11.    
    12.     delete [] p; // trả lại đất cho chính quyền
    13.     cout << p[0] << "  " << p[1] << endl; // xem chính quyền làm gì với ruộng rau và chuồng lợn
    14.    
    15.     system("pause");
    16.     return 0;
    17. }
    kết quả là em không thấy ruộng rau và chuồng lợn đâu nữa


    em nghĩ có hai nguyên nhân
    • Thứ nhất: chính quyền đã làm gì đó với ruộng rau và chuông lợn của em (sửa đổi nội dung của vùng nhớ mà trước đó p trỏ tới, thay đổi 8888 và 9999) nhưng như anh nói nó không can thiệp vào.
    • Thứ hai: em nhìn nhầm sang một khu đất khác chứ không phải khu đất lúc trước nữa. Nhưng anh nói sau khi bị tứoc đoạt quyền sử dụng đất thì em vẫn nhìn vào khu đất đó (p vẫn trỏ tới vùng nhớ mà trước đó nó trỏ tới)

    Nếu thế thì em không giải thích được kết quả của chương trình trên. Anh giải thích kỹ hơn giùm em với. Cám ơn anh

    xin khẳng định lại 1 lần nữa, e đã hiểu hoàn toàn sai lầm, FREE và DEL ko bao giờ thay đổi giá trị của con trỏ, hãy phân việt rõ ràng giữa giá trị của con trỏ và giá trị nó trỏ đến

    free nó là void free(void *mem) vậy thì xin hỏi con trỏ mem làm sao có thể thay đổi giá trị qua hàm này (xin hãy đọc bài bản chất con trỏ trong C để hiểu sâu hơn vấn đề này, tip : phân biệt rõ ràng giữa giá trị của mem và giá trị của thằng mà mem trỏ tới)


    check lại đoạn code sau đây
    C++ Code:
    1. #include <iostream>
    2. using namespace std;
    3.  
    4. int main(){
    5.     int *p;
    6.  
    7.     p= new int[2]; // xin chính quyền cấp hai khu đất
    8.     p[0]=8888; // khu này trồng rau
    9.     p[1]=9999; // khu này nuôi lợn
    10.     cout << p[0] << "  " << p[1] << endl; // giá trị trỏ đến
    11.     printf("%x\n",p);     // giá trị của p <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    12.    
    13.  
    14.     delete [] p; // trả lại đất cho chính quyền
    15.     cout << p[0] << "  " << p[1] << endl; // xem chính quyền làm gì với ruộng rau và chuồng lợn
    16.     printf("%x\n",p); // giá trị của p  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    17.  
    18.     system("pause");
    19.     return 0;
    20. }



    điều nữa
    Giải bộ nhớ hoạt động như thế nào : bản chất là trả lại quyền sử dụng
    khi này :
    + sở sẽ thu lại quyền sử dụng đất của anh, thế là đủ rồi, sở ko cần phải động chạm sửa chữa lại gì vùng đất đó. Nên khi đó dù vùng đất đó đã được giải phóng nhưng mà hoa màu của a ta trên đó thì vẫn còn, ko có biến mất được

    điều này giải thích tại sao khi mà nhiều bạn thử giải phóng bộ nhớ rồi, delete rồi, free rồi mà khi in thử ra vẫn thấy kết quả như thế .
    đơn giản thôi, a ta trả lại mảnh đất đó, nhưng chưa có ai thuê nó cả, chưa có ai sử dụng nên hôm sau ra xem thử thì nó vẫn như hôm trước khi a ta trả lại
    giả sử ngay khi em vừa trả , có thằng khác nó đến thuê luôn thì lập tức nó bỏ hoa màu của em đi, trồng hoa màu khác thì em quay lại làm gì còn thời đại này nhanh như ăn cắp ý mà

    (windows có bao nhiêu process, thread,? nên việc bị thuê ngay lập tức là quá bình thường, em à, đặc biệt nếu là hàng nằm trên stack thì thay đổi liên tục là bt)


    More :
    Trích dẫn Nguyên bản được gửi bởi first_pace Xem bài viết
    Thanks anh, giá trị của con trỏ và giá trị của vùng nhớ mà con trỏ trỏ tới thì em biết. Em chỉ thắc mắc không hiểu tại sao khi kiểm tra lại thì giá trị của vùng nhớ lại bị thay đổi (8888 và 9999) nên em với đặt ra hai khả năng:
    • Thứ nhất: chính quyền đã làm gì đó với ruộng rau và chuông lợn của em (sửa đổi nội dung của vùng nhớ mà trước đó p trỏ tới, thay đổi 8888 và 9999) nhưng như anh nói nó không can thiệp vào.
    • Thứ hai: em nhìn nhầm sang một khu đất khác chứ không phải khu đất lúc trước nữa. Nhưng anh nói sau khi bị tứoc đoạt quyền sử dụng đất thì em vẫn nhìn vào khu đất đó (p vẫn trỏ tới vùng nhớ mà trước đó nó trỏ tới)

    Và theo câu trả lời của anh nó là khả năng thứ nhất, bị thằng nào đó thuê lại ngay sau đó:

    Thanks anh đã giải đáp đoạn này, em không biết là nó lại bị thuê luôn như thế, em hiểu rồi
    khi em cài hook bắt các API trên window sẽ thấy LocalAlloc, RemoteAlloc,GlobalAlloc... được xài rất nhiều lần trên /1s chứ ko phải (ví dụ nhỏ xem ở hình dưới , đó là chỉ trong 1 tiến trình firefox thôi đó, chứ ko phải xét trên 5x process đang chạy)


    tuy nhiên đối với các môi trường cũ, đặc biệt như trên borland C for dos thì hiện tượng free rồi mà còn tài nguyên rất hay xảy ra, có rât rất nhiều người hiểu lầm là lỗi, rồi ... (đã có rất nhiều câu hỏi như thế trong box thắc mắc C). đó là lý do vì sau a phải nhấn mạnh điều đó

    Attached Thumbnails Attached Thumbnails bonho.jpg  
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.
    Đã được chỉnh sửa lần cuối bởi langman : 22-10-2012 lúc 09:54 PM. Lý do: Update
    ^_,^

    Facebook : https://www.facebook.com/langmaninternet

    Bùi Tấn Quang

  2. #2
    Ngày gia nhập
    08 2010
    Bài viết
    58

    Hay quá nhỉ, ví dụ sinh động ghê. hi hi.
    Nhân tiện cho em hỏi, nếu mình khai báo 1 mảng có thể có rất nhiều phần tử thì bộ nhớ của nó sẽ được lấy từ đâu ra (Ổ cứng, Ram.... Hay là một cái gì đó mà em không biết :P). Khi em khai báo 1 mảng int a[1000000] thì nó báo là "Array size too large". Mới có 1000000 phần tử nó đã coi là lớn thì những bài toán thực tế vài triệu phần tử liền thì phải làm thế nào? hix
    Và cái "Program heap size" có phải là bộ nhớ để cấp phát động không ạ? Mình chỉ được cấp phát tối đa là 640KB?
    Em đang dùng BC 3.0
    Cám ơn anh nhé (em xem mấy cái chap unikey của anh mà không hiểu gì. hix)
    Đã được chỉnh sửa lần cuối bởi tieuyeu_ht91 : 09-09-2010 lúc 09:07 AM.
    Sẽ không buồn vì những điều ta chưa làm được...

  3. #3
    Ngày gia nhập
    06 2007
    Nơi ở
    C:\WINDOWS\system32\dllcache\
    Bài viết
    3,007

    int a[1000000] ; khai báo ở đâu ?
    em khai báo ở sở (tức là khai báo dạng local, trong các hàm )thì sở nó xin vùng nhớ ở stack segment, mà stack segment thì đây (trong ảnh, nhỏ gọn thế này, liệu nó có cho em vùng lớn thế kia ko 1000000*4byte)
    ^_,^

    Facebook : https://www.facebook.com/langmaninternet

    Bùi Tấn Quang

  4. #4
    Ngày gia nhập
    01 2008
    Bài viết
    240

    thanks,
    hay quá, xin hỏit dùng cái phần mềm gì để theo chụp được cái image như cậu
    Đã được chỉnh sửa lần cuối bởi nthung : 09-09-2010 lúc 04:04 PM.
    Time

  5. #5
    Ngày gia nhập
    08 2010
    Bài viết
    58

    Trích dẫn Nguyên bản được gửi bởi langman Xem bài viết
    int a[1000000] ; khai báo ở đâu ?
    em khai báo ở sở (tức là khai báo dạng local, trong các hàm )thì sở nó xin vùng nhớ ở stack segment, mà stack segment thì đây (trong ảnh, nhỏ gọn thế này, liệu nó có cho em vùng lớn thế kia ko 1000000*4byte)
    Em khai báo trong hàm main(); thế nếu em khai báo là mảng toàn cục thì nó lấy ở đâu ra. (xin anh đừng lấy ví dụ cấp đất nữa, làm em thèm)
    Sẽ không buồn vì những điều ta chưa làm được...

  6. #6
    Ngày gia nhập
    06 2007
    Nơi ở
    C:\WINDOWS\system32\dllcache\
    Bài viết
    3,007

    Mặc định Bản chất của việc cấp phát bộ nhớ động và giải phóng bộ nhớ

    Trích dẫn Nguyên bản được gửi bởi nthung Xem bài viết
    thanks,
    hay quá, xin hỏit dùng cái phần mềm gì để theo chụp được cái image như cậu
    dùng công cụ khá nổi tiếng này
    PHP Code:
    http://forums.congdongcviet.com/attachment.php?attachmentid=3390&d=1282152390 
    Trích dẫn Nguyên bản được gửi bởi tieuyeu_ht91 Xem bài viết
    Em khai báo trong hàm main(); thế nếu em khai báo là mảng toàn cục thì nó lấy ở đâu ra. (xin anh đừng lấy ví dụ cấp đất nữa, làm em thèm)
    các hằng và biến tĩnh nằm data segment,
    ^_,^

    Facebook : https://www.facebook.com/langmaninternet

    Bùi Tấn Quang

  7. #7
    Ngày gia nhập
    05 2010
    Nơi ở
    Cách Mạng Tháng 8
    Bài viết
    205


    @tieuyeu_ht91 : cậu phải cấp phát động mới được lớn như thế chứ
    Nothing last forever !!

  8. #8
    Ngày gia nhập
    08 2010
    Bài viết
    58

    Trích dẫn Nguyên bản được gửi bởi Nature Master Xem bài viết

    @tieuyeu_ht91 : cậu phải cấp phát động mới được lớn như thế chứ
    Cấp phát động thì nó lấy bộ nhớ từ đâu vậy cà.

    "data segment"
    Là cái gì thế em dịch là dữ liệu phân đoạn, nghĩa là sao đây, anh langman bận rộn thế :P:P
    Sẽ không buồn vì những điều ta chưa làm được...

  9. #9
    Ngày gia nhập
    06 2007
    Nơi ở
    C:\WINDOWS\system32\dllcache\
    Bài viết
    3,007

    đã update câu trả lời cho em, xem ở #1
    ^_,^

    Facebook : https://www.facebook.com/langmaninternet

    Bùi Tấn Quang

  10. #10
    Ngày gia nhập
    08 2010
    Bài viết
    58

    Trích dẫn Nguyên bản được gửi bởi langman Xem bài viết
    đã update câu trả lời cho em, xem ở #1
    Cám ơn anh, rất chi tiết, giờ thì em thực sự hiểu rồi
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.
    Sẽ không buồn vì những điều ta chưa làm được...

Các đề tài tương tự

  1. Trả lời: 1
    Bài viết cuối: 09-03-2014, 08:09 PM
  2. Trả lời: 0
    Bài viết cuối: 07-05-2013, 09:40 AM
  3. Trả lời: 1
    Bài viết cuối: 09-03-2013, 10:08 AM
  4. Chung Cư 257 Giải Phóng, st/cn Chung Cư 257 Giải Phóng với DT: 81m, 33tr
    Gửi bởi datphat191 trong diễn đàn Giới thiệu website, sản phẩm của bạn
    Trả lời: 0
    Bài viết cuối: 16-02-2012, 01:37 PM
  5. Giải phóng bộ nhớ như thế nào để chương trình chạy nhanh?
    Gửi bởi toanhoi trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 3
    Bài viết cuối: 03-09-2010, 01:14 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn