Trang 5 trên tổng số 5 Đầu tiênĐầu tiên ... 345
Từ 41 tới 48 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. #41
    Ngày gia nhập
    04 2013
    Nơi ở
    sống và làm việc tại computer
    Bài viết
    15

    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ớ

    Cảm ơn bạn langman nhiều, giờ mới hiểu hơn về cấp phát.

  2. #42
    Ngày gia nhập
    09 2014
    Bài viết
    1

    Các cao nhân giải đáp giùm.

    Mình k thể Free được biến con trỏ cấu trúc.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    typedef int element;
    typedef struct basicnode {
    	element inf;
    	basicnode *next, *prev;
    } *node;
    typedef struct basiclist {
    	node head; 
    	node tail; 
    } *list; 
    list Initialize() {
    	list ds = (list)malloc(sizeof(list));
    	if (!ds) {
    		printf ("MEMORY FULL!!! No memory to access!");
    		return NULL;
    	}
    	ds->head = NULL; 
    	ds->tail = NULL; 
    	return (ds); 
    }
    node Create_Node() {
    	node temp = (node)malloc(sizeof(node)); 
    	if (!temp) {
    		printf ("MEMORY FULL!!! No memory to access!");
    		return NULL;
    	}
    	temp->next = NULL; 
    	temp->prev = NULL; 
    	return (temp); 
    }
    void Add_head(list  ds, element x) {
    	node NewNode = Create_Node(); 
    	if (!NewNode) return; 
    	if (!ds->head) ds->head = ds->tail = NewNode; 
    	else {
    		NewNode->inf = x;
    		NewNode->next = ds->head; 
    		ds->head->prev = NewNode; 
    		ds->head = NewNode; 
    	}
    }
    void Add_Last(list  ds, element x) {
    	node NewNode = Create_Node(); 
    	if (!NewNode) return; 
    	NewNode->inf = x;
    	if (!ds->tail) ds->head = ds->tail = NewNode; 
    	else {
    		ds->tail->next = NewNode; 
    		NewNode->prev = ds->tail; 
    		ds->tail = NewNode; 
    	} 
    }
    node Add_Mid(list ds, element x, node  InsNode) {
    	node NewNode = Create_Node(); 
    	if (!NewNode) return (NULL); 
    	if (!InsNode->next) {
    		InsNode->next = NewNode; 
    		NewNode->prev = InsNode; 
    		ds->tail = NewNode; 
    	}
    	else {
    		NewNode->next = InsNode->next; 
    		InsNode->next->prev = NewNode; 
    		InsNode->next = NewNode; 
    		NewNode->prev = InsNode; 
    	}
    	return (NewNode); 
    }
    node Searching(list ds, element SearchData) {
    	node CurNode = ds->head; 
    	while (CurNode) {
    		if (CurNode->inf == SearchData) return CurNode; 
    		CurNode = CurNode->next; 
    	} 
    	return CurNode; 
    }
    void Delete_Node (list  ds, element DelData) {
    	node DelNode = Searching(ds, DelData); 
    	if (!DelNode) return; 
    	if (!DelNode->next && !DelNode->prev) ds->head = ds->tail = NULL; 
    	else 
    		if (!DelNode->prev) {
    			ds->head = ds->head->next; 
    			ds->head->prev = NULL; 
    		}
    		else 
    			if (!DelNode->next) {
    				ds->tail = ds->tail->prev; 
    				ds->tail->next = NULL; 
    			}
    			else {
    				DelNode->prev->next = DelNode->next; 
    				DelNode->next->prev = DelNode->prev; 
    			}
    	free (DelNode); 
    }
    void Delete (list  ds) {
    	node TempNode = ds->head; 
    	while (TempNode) {
    		TempNode = TempNode->next; 
    		/*free(ds->head); */
    		ds->head = TempNode;
    	}
    	return; 
    }
    list Create(list  ds, int N) {
        ds = Initialize();
    	element NewData; 
    	for (int i = 0; i < N; i++) {
    		printf ("Nhap du lieu thu %d:", i+1); scanf ("%d", &NewData);
    		Add_Last(ds, NewData); 
    	} 
    	return (ds);
    }
    void Bubble_Sort (list ds) {
    	node Inode = ds->head; 
    	element temp;
    	if (!Inode) return; 
    	while (Inode != ds->tail) {
    		node Jnode = ds->tail; 
    		while (Jnode != Inode) {
    			if (Jnode->inf < Jnode->prev->inf) {
    				temp = Jnode->inf;
    				Jnode->inf = Jnode->prev->inf;
    				Jnode->prev->inf = temp;
    			}
    			Jnode = Jnode->prev; 
    		}
    		Inode = Inode->next; 
    	}
    }
    int main() {
    	list ds;
    	node dp;
    	int i;
    	ds = Create(ds, 5); 
    	for (dp = ds->head; dp; dp= dp->next) printf ("%d ", dp->inf);printf ("\n");
    	Bubble_Sort(ds);
    	printf ("Danh sach tang dan:\n");
    	for (dp = ds->head; dp; dp= dp->next) printf ("%d ", dp->inf);printf ("\n");
    	dp = Searching(ds, 5);
    	if (dp) printf ("%d\n", dp->inf); else printf ("Khong co phan tu 15 trong danh sach.\n");
    	if (dp)  {
    		Delete_Node(ds, 5);
    		printf ("Danh sach sau khi xoa phan tu 5: \n");
    		for (dp = ds->head; dp; dp= dp->next) printf ("%d ", dp->inf);
    	}
    	else printf ("Khong co phan tu 5 trong danh sach.");
    	Delete(ds);
    	for (dp = ds->head; dp; dp= dp->next) printf ("%d ", dp->inf); printf ("\n");
    	return 0;
    }

  3. #43
    Ngày gia nhập
    08 2010
    Bài viết
    82

    Bác Langman cho em hỏi về cơ chế cấp phát cho biến toàn cục và biến địa phương với. Tôi có một bài như thế này:
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    int main()
    {
    FILE *f;
    int n, a[1000001], i;//*
    f=fopen("bai1.inp","r");
    fscanf(f,"%d",&n);
    for(i=0; i<n; i++){
    fscanf(f,"%d",&a[i]);
    printf("%d, ", a[i]);
    }
    fclose(f);
    }
    Dịch không bị lỗi nhưng khi chạy lại không đọc được file bai1.inp (file này có chứa 1 số nguyên N và dòng 2 chứa N số nguyên cách nhau dấu cách). Nếu tôi đưa chỗ khai báo (*) lên toàn cục thì lại được bác ạ.
    Cảm ơn bác.

  4. #44
    Ngày gia nhập
    05 2013
    Bài viết
    1

    Thế cho mình hỏi:

    Theo như trình bày ở trên của langman, vậy thì khi khai báo 1 biến con trỏ nó sẽ tồn tại mãi mãi hay sao, dù cho mình có set free chăng nữa? Như thế nếu mình khai báo vô số biến con trỏ, thì làm sao hệ thống phòng tránh được chuyện này khi bộ nhớ là có hạn?

    Và bạn có suy nghĩ gì khi mình làm thế này

    free(p);
    p=NULL;

    Khi làm thế này biến con trỏ mình đã mất hoàn toàn chưa? hay nó vẫn tồn tại ngoại trừ địa chỉ ô nhớ của mình là NULL?

  5. #45
    Ngày gia nhập
    01 2013
    Bài viết
    1,479

    Trích dẫn Nguyên bản được gửi bởi levan1088 Xem bài viết
    Theo như trình bày ở trên của langman, vậy thì khi khai báo 1 biến con trỏ nó sẽ tồn tại mãi mãi hay sao, dù cho mình có set free chăng nữa? Như thế nếu mình khai báo vô số biến con trỏ, thì làm sao hệ thống phòng tránh được chuyện này khi bộ nhớ là có hạn?
    Bây giờ cấp phát động là gần 100% (OOP :trollface: ), nhả ra là có người hốt liền.
    Trích dẫn Nguyên bản được gửi bởi levan1088 Xem bài viết
    Và bạn có suy nghĩ gì khi mình làm thế này

    free(p);
    p=NULL;

    Khi làm thế này biến con trỏ mình đã mất hoàn toàn chưa? hay nó vẫn tồn tại ngoại trừ địa chỉ ô nhớ của mình là NULL?
    Thực ra để quản lí bộ nhớ heap thì có những cái list, mỗi list ứng với từng (block) size cụ thể.
    Khi bạn malloc thì 1 block đc đánh dấu cho bạn luôn chứ ko cho lẻ tẻ.
    Đã được chỉnh sửa lần cuối bởi prog10 : 22-12-2014 lúc 10:52 PM.

  6. #46
    Ngày gia nhập
    10 2014
    Bài viết
    3

    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 soldtheworld Xem bài viết
    Bác Langman cho em hỏi về cơ chế cấp phát cho biến toàn cục và biến địa phương với. Tôi có một bài như thế này:
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    int main()
    {
    FILE *f;
    int n, a[1000001], i;//*
    f=fopen("bai1.inp","r");
    fscanf(f,"%d",&n);
    for(i=0; i<n; i++){
    fscanf(f,"%d",&a[i]);
    printf("%d, ", a[i]);
    }
    fclose(f);
    }
    Dịch không bị lỗi nhưng khi chạy lại không đọc được file bai1.inp (file này có chứa 1 số nguyên N và dòng 2 chứa N số nguyên cách nhau dấu cách). Nếu tôi đưa chỗ khai báo (*) lên toàn cục thì lại được bác ạ.
    Cảm ơn bác.
    Khi bác khai báo biến trong hàm main, nó sẽ đc cấp phát trên stack, mà stack chỉ đc cấp cho ứng dụng 1 lần và bị giới hạn bởi linker, tối đa 1 MB(có thể chỉnh lại đc) => mảng của bác 4MB sẽ báo lỗi segment fault.

    Khi mảng a[] khai báo toàn cục, nó được cấp phát 1 lần ở phân vùng nằm ngoài stack và heap (gọi là BSS) khi chạy ứng dụng, và vùng này cũng như heap, chỉ bị giới hạn theo khả năng của máy.



    Trích dẫn Nguyên bản được gửi bởi levan1088 Xem bài viết
    Thế cho mình hỏi:

    Theo như trình bày ở trên của langman, vậy thì khi khai báo 1 biến con trỏ nó sẽ tồn tại mãi mãi hay sao, dù cho mình có set free chăng nữa? Như thế nếu mình khai báo vô số biến con trỏ, thì làm sao hệ thống phòng tránh được chuyện này khi bộ nhớ là có hạn?

    Và bạn có suy nghĩ gì khi mình làm thế này

    free(p);
    p=NULL;

    Khi làm thế này biến con trỏ mình đã mất hoàn toàn chưa? hay nó vẫn tồn tại ngoại trừ địa chỉ ô nhớ của mình là NULL?
    Bạn nên nhớ biến con trỏ cũng như bao biến khác (cục bộ hay toàn cục), sẽ được giải phóng khi ra khỏi scope, chỉ có vùng nhớ được trỏ bởi nó mới còn lại
    Do đó:
    free(p): vùng nhớ trỏ bởi p đc đánh dấu free, biến p ko thay đổi.
    đến đây p vẫn đang trỏ tới vùng nhớ ban nãy, tuy nhiên nó ko đc kiểm soát vùng nhớ đó dẫn tới có thể 1 tiến trình khác truy cập vào và làm thay đổi giá trị vùng nhớ. Nếu bạn sử dụng p lúc này
    sẽ ra sai kết quả.
    p = NULL: đảm bảo ko sử dụng được vùng nhớ ban nãy.

  7. #47
    Ngày gia nhập
    06 2015
    Bài viết
    1

    Mặc định Có phải lỗi khi cấp phát lượng lớn bộ nhớ động?

    Trước đây em có làm một bài tập về đọc dữ liệu từ một tập tin từ điển, sau đó đưa dữ liệu đó vào cây nhị phân tìm kiếm AVL. Khi viết xong em chạy với bộ thử nhỏ (khoảng vài trăm từ) thấy đúng nên coi như hoàn thành. Gần đây em sử dụng lại cũng mã nguồn ấy với bộ từ điển lớn (vài trăm nghìn từ) thì thấy sai. Sau khi các từ (từ khoảng vài nghìn trở đi) được thêm vào và tiến hành cân bằng thì cây không còn giữ đúng thứ tự.

    Em đã thử tách riêng các hàm và chạy thì đều đúng (các hàm so sánh, thêm nút, quay trái/phải, cân bằng), khi gộp các hàm lại chạy với bộ thử vài nghìn từ vẫn đúng, nhưng nhiều hơn nữa thì sai. Em chạy bắt lỗi được vị trí nhánh sai (từ làm cho sai), sau đó cắt bộ thử từ khoảng 1000 từ trước nó đến 1000 từ sau nó) thì kết quả lại đúng.

    Cuối cùng em nghĩ là do sử dụng cấp phát động (malloc()) vì lí do nào đó mà các địa chỉ bị trùng (chất lên nhau) làm quá trình thêm vào bị sai thứ tự (cái này là em phỏng đoán). Vì em đã thử tách từ điển ra làm nhiều đoạn (mỗi đoạn vài nghìn từ) bất kì thì không có đoạn nào chạy sai. Để ý bắt lỗi nhiều lần chỉ sai ở từ thứ vài nghìn trở đi (bất kể đoạn nào). Sau đó đã lên mạng tìm hiểu thì biết malloc() thỉnh thoảng không thể đáp ứng được yêu cầu cấp phát bộ nhớ và trả về NULL. Sau đó em dùng toán tử new thay cho malloc() thì kết quả vẫn vậy.

    Liệu có ai đã bị những lỗi tương tự như vầy chưa và lí do có phải nằm ở vấn đề bộ nhớ? Theo em biết cấp phát động là sử dụng bộ nhớ RAM, mà không có chuyện cấp phát vài nghìn từ lại hết ram được (em tính thử chỉ khoảng mấy chục MB). Em cũng không thể tin đây là lỗi logic của mã nguồn vì khi không mấy nghìn từ đầu tiên không bao giờ sai, đến đúng khoảng vài nghìn trở đi thì sai một cách khó hiểu.

    Ai giải đáp dùm em với. Em cảm ơn.

  8. #48
    Ngày gia nhập
    06 2015
    Bài viết
    2

    Langman có thể nói rõ hơn về cấp phát động mảng cấu trúc không ạ ?

Trang 5 trên tổng số 5 Đầu tiênĐầu tiên ... 345

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