zoukankan      html  css  js  c++  java
  • 谈谈 C++ 内存管理

    有多少个new就有多少个delete

    二维动态数组的写法

    1. 首先开辟第一维的空间,第一维是char型的指针
    char   **s = new char*[182];
    1. 在第一维的基础上,开辟第二维的空间,第二维是不定长度的char型
    s[nCounts] = new char[str.length()];
    1. 释放二维动态数组时,规则是由内到外的,先释放第二维的空间,最后再释放第一维的空间
    for (int i = 0; i < nCounts; ++i) {
    
    delete[] s[i];  // delete[col] s[i];
    
    s[i] = NULL;
    
    }
    
    delete[] s;  // delete[row] s;
    
    s = NULL;

    s是二维指针,(声明)定义在main函数内,既然定义时在函数内,那么s指针就存放在内存中的栈区域中,使用new动态开辟的空间是在堆区域,堆区域用于存放数据,当然,每个数据都有它的内存地址,因此数据的地址是堆中的某一块地址,而栈中的s只是一个指针,这个指针指向堆区域的指定一块地址,当使用delete释放第二维的空间时,实质是回收堆上的虚拟地址块,而栈内的指针s并无发生变化

    实现代码:

     1 ///: handleString
     2 #include <cstdlib>
     3 #include <string>
     4 #include <vector>
     5 #include <fstream>
     6 #include <iostream>
     7 #include <algorithm>
     8 
     9 using namespace std;
    10 
    11 int
    12 main(void) {
    13   ifstream fin("E:\\totaldata.txt");
    14   ofstream fout("E:\\result.txt");
    15   
    16   char   **s = new char*[182];
    17 
    18   int    nCounts = 0;
    19   string str;
    20   vector<string> vect;
    21   vector<string>::const_iterator iter;
    22 
    23   while (getline(fin, str, '\n')) {
    24     remove(str.begin(), str.end(), ' ');
    25     int pos = str.find('>');
    26     str.erase(str.begin(), str.begin() + pos + 1);
    27     
    28     vect.push_back(str);
    29     
    30     s[nCounts] = new char[str.length()];
    31     strncpy(s[nCounts], str.c_str(), str.length());
    32     fout << nCounts + 1 << " " << s[nCounts++] << endl << endl;
    33 //     char* s = new char[str.length()];
    34 //     strcpy(s, str.c_str());
    35 //     fout << nCounts++  << " " << s << endl << endl;
    36 
    37 //     delete  [] s;
    38   }// End of While
    39   for (int i = 0; i < nCounts; ++i) {
    40 // //     int col = strlen(s[i]);
    41 // //     delete[] s;
    42     delete[] s[i];
    43   }
    44   delete[] s;
    45 
    46   fin.close();
    47   fout.close();
    48   return 0;
    49 }

    一开始使用strcpy,但是出错了,原因是没有在s[nCounts]末尾加上’\0’!

    如果已经知道第一维的长度,假设是182,那么可以参考这种写法

    1. 定义
    char   *s[182] = {NULL};
    1. 动态开辟第二维数组空间
    s[nCounts] = new char[str.length()];
    1. 释放动态数组时,因为第一维已经是事先设定好的,实质上使用new申请的堆空间只有第二维,因此只需要释放第二维的堆空间
    for (int i = 0; i < nCounts; ++i) {
    
        delete[] s[i];
    
      }

    S是在main函数中定义的,因此指针数组s存放在栈空间中,栈空间存放的是182个char类型的指针,使用new为第二维开辟的空间是在堆区域,栈空间是不能回收的,因为栈是后进先出的,而且栈内保存的不只是变量,还有调用函数的地址(EIP)等等,而堆是需要回收的,如果使用new开辟一块空间,除非是使用delete回收或直到程序运行结束,否则是永远不会自动回收的,因此只能对第二维使用delete来回收堆空间

    实现的代码如下:

     1 ///: handleString
     2 #include <cstdlib>
     3 #include <string>
     4 #include <vector>
     5 #include <fstream>
     6 #include <iostream>
     7 #include <algorithm>
     8 
     9 using namespace std;
    10 
    11 int
    12 main(void) {
    13   ifstream fin("E:\\totaldata.txt");
    14   ofstream fout("E:\\result.txt");
    15   
    16   char   *s[182] = {NULL};
    17   
    18   int    nCounts = 0;
    19   string str;
    20   vector<string> vect;
    21   vector<string>::const_iterator iter;
    22   
    23   while (getline(fin, str, '\n')) {
    24     remove(str.begin(), str.end(), ' ');
    25     int pos = str.find('>');
    26     str.erase(str.begin(), str.begin() + pos + 1);
    27     
    28     vect.push_back(str);
    29     str += '\0';
    30     
    31     s[nCounts] = new char[str.length()];
    32     strcpy(s[nCounts], str.c_str());
    33     fout << nCounts + 1 << " " << s[nCounts++] << endl << endl;
    34     //     char* s = new char[str.length()];
    35     //     strcpy(s, str.c_str());
    36     //     fout << nCounts++  << " " << s << endl << endl;
    37     
    38     //     delete  [] s;
    39   }// End of While
    40   for (int i = 0; i < nCounts; ++i) {
    41 //     // //     int col = strlen(s[i]);
    42 //     // //     delete[] s;
    43 //     int slen = strlen(s[i]);
    44 //     cout << &s[i] << " " << (s + i) << endl;
    45 //      delete[] s[i];
    46     char** ptr = (s + i);
    47     cout << &s[i] << " " << ptr << endl;
    48     delete[] ptr;
    49 //     delete[] (s + i * (strlen(s[i]) + 1));
    50   }
    51 //   delete[] s;
    52   
    53   fin.close();
    54   fout.close();
    55   return 0;
    56 }
  • 相关阅读:
    Spring事务的传播行为案例详细分析
    面试官:InnoDB一棵B +树可以存放多少行数据?
    Java面试题——数组求和统计
    Java算法题——牛牛消消乐
    Jenkins集成GitLab
    Kafka+ZooKeeper高可用集群部署
    Linux运维不会这些,别做工程师
    Linux系统通过Squid配置实现代理上网
    使用Openresty实现WAF防火墙功能
    谷歌浏览器插件(下载百度云盘)
  • 原文地址:https://www.cnblogs.com/yewei/p/2922949.html
Copyright © 2011-2022 走看看