二维数组分配,释放空间

http://blog.youkuaiyun.com/xcyangfan/article/details/7055028



二维数组申请与释放

[cpp]  view plain copy
  1. int nGLen=10000;//Graph length   
  2. int **test=new int* [nGLen];   
  3. for (int g=0;g <nGLen;g++)   
  4. {//malloc buffer   
  5.     test[g] = new int[MAX_GROUP_WORD_COUNT];   
  6. }   
  7.   
  8. finish = clock();    
  9. duration = finish - start;    
  10. printf( "buffer: %d\n", duration );    
  11. start=clock();   
  12.   
  13. //////////////////////////////////////////////////////////////////////////   
  14. //free temp buffer   
  15. //////////////////////////////////////////////////////////////////////////   
  16. for (int g=0;g <nGLen;g++)   
  17. {   
  18.     delete [] test[g];   
  19. }   
  20. delete [] test;   

你这根本不是“二维数组”,二维数组要求连续的地址空间,这样一次分配对应一次释放。你这个是指针一维数组,每个指针分别指向一块内存而已,只是访问方法上有点象二维数组而已。


个人不建议使用这样的二维数组。这样使用,最大的问题在于造成空间上的无数碎片,如果第一维元素多,那么循环分配和循环释放也会导致性能的极端下降。

使用所谓的二维转一维方法吧,也就是对于二维数组A[M]{N]和一维数组B[M*N],其A[i][j]等价于B[i*N+j},这样你就不需要用这么低效率的内存分配方式了


test[N][M]和**test分配的二维数组是有区别的,在test[N][M]中,相邻数之间是连续存储的,而在**test中,分配的每行之间的元素是连续的,但是行与行之间并不是连续的。
 堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小。这样,代码中的delete语句才能正确的释放本内存空间。最后,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。
你的动态分配的内存太大,而且分配次数较多,所以时间长
不是不乾淨,只是你釋放的那塊記憶體還沒人使用,所以資料還是原本的,
雖然能顯示,但是沒辦法寫入。



[cpp]  view plain copy
  1. //c++builder 帮助文件中的范例 Example of the new and delete Operators with multi-dimensional arrays:  
  2.   
  3. // ALLOCATE A TWO-DIMENSIONAL SPACE, INITIALIZE, AND DELETE IT.  
  4.   
  5. #include <exception>  
  6. #include <iostream>  
  7.   
  8. using std::cout;  
  9. using std::endl;  
  10. void display(long double **);  
  11. void de_allocate(long double **);  
  12.   
  13. int m = 3;                               // THE NUMBER OF ROWS.  
  14. int n = 5;                               // THE NUMBER OF COLUMNS.  
  15.   
  16. int main(void) {  
  17.    long double **data;  
  18.   
  19.    try {                                 // TEST FOR EXCEPTIONS.  
  20.       data = new long double*[m];        // STEP 1: SET UP THE ROWS.  
  21.       for (int j = 0; j < m; j++)  
  22.   
  23.           data[j] = new long double[n];  // STEP 2: SET UP THE COLUMNS  
  24.       }  
  25.    catch (std::bad_alloc) {  // ENTER THIS BLOCK ONLY IF bad_alloc IS THROWN.  
  26.       // YOU COULD REQUEST OTHER ACTIONS BEFORE TERMINATING  
  27.       cout << "Could not allocate. Bye ...";  
  28.       exit(-1);  
  29.       }  
  30.   
  31.    for (int i = 0; i < m; i++)  
  32.       for (int j = 0; j < n; j++)  
  33.           data[i][j] = i + j;            // ARBITRARY INITIALIZATION  
  34.   
  35.    display(data);  
  36.    de_allocate(data);  
  37.    return 0;  
  38.   
  39.    }  
  40.   
  41. void display(long double **data) {  
  42.    for (int i = 0; i < m; i++) {  
  43.         for (int j = 0; j < n; j++)  
  44.              cout << data[i][j] << " ";  
  45.        cout << "\n" << endl;  
  46.        }  
  47.    }  
  48.   
  49. void de_allocate(long double **data) {  
  50.    for (int i = 0; i < m;  i++)  
  51.        delete[] data[i];                 // STEP 1: DELETE THE COLUMNS  
  52.   
  53.    delete[] data;                        // STEP 2: DELETE THE ROWS  
  54.   
  55.    }  

二维数组申请与释放

[cpp]  view plain copy
  1. int nGLen=10000;//Graph length   
  2. int **test=new int* [nGLen];   
  3. for (int g=0;g <nGLen;g++)   
  4. {//malloc buffer   
  5.     test[g] = new int[MAX_GROUP_WORD_COUNT];   
  6. }   
  7.   
  8. finish = clock();    
  9. duration = finish - start;    
  10. printf( "buffer: %d\n", duration );    
  11. start=clock();   
  12.   
  13. //////////////////////////////////////////////////////////////////////////   
  14. //free temp buffer   
  15. //////////////////////////////////////////////////////////////////////////   
  16. for (int g=0;g <nGLen;g++)   
  17. {   
  18.     delete [] test[g];   
  19. }   
  20. delete [] test;   

你这根本不是“二维数组”,二维数组要求连续的地址空间,这样一次分配对应一次释放。你这个是指针一维数组,每个指针分别指向一块内存而已,只是访问方法上有点象二维数组而已。


个人不建议使用这样的二维数组。这样使用,最大的问题在于造成空间上的无数碎片,如果第一维元素多,那么循环分配和循环释放也会导致性能的极端下降。

使用所谓的二维转一维方法吧,也就是对于二维数组A[M]{N]和一维数组B[M*N],其A[i][j]等价于B[i*N+j},这样你就不需要用这么低效率的内存分配方式了


test[N][M]和**test分配的二维数组是有区别的,在test[N][M]中,相邻数之间是连续存储的,而在**test中,分配的每行之间的元素是连续的,但是行与行之间并不是连续的。
 堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小。这样,代码中的delete语句才能正确的释放本内存空间。最后,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。
你的动态分配的内存太大,而且分配次数较多,所以时间长
不是不乾淨,只是你釋放的那塊記憶體還沒人使用,所以資料還是原本的,
雖然能顯示,但是沒辦法寫入。



[cpp]  view plain copy
  1. //c++builder 帮助文件中的范例 Example of the new and delete Operators with multi-dimensional arrays:  
  2.   
  3. // ALLOCATE A TWO-DIMENSIONAL SPACE, INITIALIZE, AND DELETE IT.  
  4.   
  5. #include <exception>  
  6. #include <iostream>  
  7.   
  8. using std::cout;  
  9. using std::endl;  
  10. void display(long double **);  
  11. void de_allocate(long double **);  
  12.   
  13. int m = 3;                               // THE NUMBER OF ROWS.  
  14. int n = 5;                               // THE NUMBER OF COLUMNS.  
  15.   
  16. int main(void) {  
  17.    long double **data;  
  18.   
  19.    try {                                 // TEST FOR EXCEPTIONS.  
  20.       data = new long double*[m];        // STEP 1: SET UP THE ROWS.  
  21.       for (int j = 0; j < m; j++)  
  22.   
  23.           data[j] = new long double[n];  // STEP 2: SET UP THE COLUMNS  
  24.       }  
  25.    catch (std::bad_alloc) {  // ENTER THIS BLOCK ONLY IF bad_alloc IS THROWN.  
  26.       // YOU COULD REQUEST OTHER ACTIONS BEFORE TERMINATING  
  27.       cout << "Could not allocate. Bye ...";  
  28.       exit(-1);  
  29.       }  
  30.   
  31.    for (int i = 0; i < m; i++)  
  32.       for (int j = 0; j < n; j++)  
  33.           data[i][j] = i + j;            // ARBITRARY INITIALIZATION  
  34.   
  35.    display(data);  
  36.    de_allocate(data);  
  37.    return 0;  
  38.   
  39.    }  
  40.   
  41. void display(long double **data) {  
  42.    for (int i = 0; i < m; i++) {  
  43.         for (int j = 0; j < n; j++)  
  44.              cout << data[i][j] << " ";  
  45.        cout << "\n" << endl;  
  46.        }  
  47.    }  
  48.   
  49. void de_allocate(long double **data) {  
  50.    for (int i = 0; i < m;  i++)  
  51.        delete[] data[i];                 // STEP 1: DELETE THE COLUMNS  
  52.   
  53.    delete[] data;                        // STEP 2: DELETE THE ROWS  
  54.   
  55.    }  
### 正确释放二维数组内存的方法 在编程中,释放动态分配二维数组内存是一个关键步骤,以避免内存泄漏。根据引用内容和专业实践,以下是几种常见的方法来释放二维数组的内存。 #### 方法一:使用指针数组的方式 当通过指针数组方式分配二维数组时,需要逐行释放每一行的内存,最后再释放指针数组本身的内存[^2]。具体实现如下: ```c int **b = new int*[row]; // 分配一个指针数组 for (int i = 0; i < row; i++) { b[i] = new int[col]; // 为每个指针分配一个数组 } // 使用完后释放内存 for (int i = 0; i < row; i++) { delete[] b[i]; // 先释放每一行的内存 } delete[] b; // 最后释放指针数组本身 b = NULL; // 将指针置为空,防止悬空指针 ``` #### 方法二:使用递归定义的方式 如果使用了 `typedef` 定义的递归类型来分配二维数组,则释放内存的操作相对简单[^2]。只需释放整个二维数组即可: ```c typedef int array[COL]; // 定义一个具有 COL 个元素的数组类型 array *a = new array[row]; // 为该一维数组(实际上二维)申请空间 // 使用完后释放内存 delete[] a; // 只需释放一次 a = NULL; // 将指针置为空,防止悬空指针 ``` #### 方法三:C语言中的动态分配释放 在 C 语言中,动态分配二维数组通常通过指针数组实现。释放内存的过程与 C++ 类似,但使用的是 `malloc` 和 `free` 函数[^1]。例如: ```c int **a = (int **) malloc(sizeof(int *) * r); // 分配指针数组 for (int j = 0; j < r; j++) { a[j] = (int *) malloc(sizeof(int) * c); // 为每一行分配内存 } // 使用完后释放内存 for (int j = 0; j < r; j++) { free(a[j]); // 先释放每一行的内存 } free(a); // 最后释放指针数组本身 a = NULL; // 将指针置为空,防止悬空指针 ``` #### 方法四:NDK 中的内存释放 在 NDK 编程中,释放 Java 数组的内存需要调用 JNI 提供的函数。以下是一个示例[^4]: ```c (*env)->ReleaseIntArrayElements(env, value, codeLineArray, 0); (*env)->ReleaseIntArrayElements(env, (jintArray)codeLineArray, codeLineData, 0); (*env)->DeleteLocalRef(env, value); (*env)->DeleteLocalRef(env, codeLineArray); (*env)->DeleteLocalRef(env, codeLineData); value = NULL; codeLineArray = NULL; codeLineData = NULL; ``` ### 注意事项 - 在释放内存时,必须按照分配的顺序反向释放,即先释放子级内存,再释放父级内存。 - 释放内存后,应将指针置为 `NULL`,以防止悬空指针问题。 - 如果程序中存在多线程操作,确保释放内存的操作是线程安全的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值