仅在一定限度内释放 2D 指针数组的内存

Posted

技术标签:

【中文标题】仅在一定限度内释放 2D 指针数组的内存【英文标题】:Deallocating memory of a 2D array of pointers only till a certain limit 【发布时间】:2018-07-10 10:25:20 【问题描述】:

我有一个使用指针动态创建的二维数组。我只想删除某些连续的行,而不是全部。这是我为删除而编写的代码:

#include <iostream>
using namespace std;

void clearMemoryAll(int **matchedIndicesArray, int rows)


  for(int i = 0; i < rows; i++)
  
    delete [] matchedIndicesArray[i];
  

  delete [] matchedIndicesArray;



int main()

  // Program having 10M x 4 = 40M elements

  int rows = 10000000;
  int **matchedStagesMatrix;
  matchedStagesMatrix = new int*[rows];

  int cols = 4;


  for(int i = 0; i < rows; i++)
  
    matchedStagesMatrix[i] = new int[cols];
    for (int j = 0; j < cols; j++)
    
      matchedStagesMatrix[i][j] = 1;
    
  



  clearMemoryAll(matchedStagesMatrix, rows);
  while (1) 


  return 0;

很明显,这段代码将删除二维数组的所有行。如何只删除某些前 100 行而不是一次全部删除?我不能简单地将 100 作为参数传递给函数,因为当控件到达函数的 for 循环之外时,它无论如何都会尝试删除完整的矩阵。应该删除矩阵,以便在删除某些行后它仍然可以使用。 我知道向量是一个不错的选择,但我很好奇指针的工作原理以及如何操纵它们而不是使用向量。

编辑:另外,我计划多次使用此删除功能,即我将多次删除矩阵行,每次只删除某些行,直到所有行都删除删除。所以不能每次都执行for循环外的最后一行。

【问题讨论】:

不使用向量吗? 假设,这必须使用指针而不是向量来完成。 您可以使用指针向量来实现这一点,删除会更容易 将表示第一个和最后一个索引的值传递给deleted,并相应地循环。您需要决定是否执行delete [] matchedIndicesArray;,并且还需要确定如果函数被多次调用且范围重叠,如何避免多次删除行(因为删除两次会产生未定义的行为)。 【参考方案1】:

如果您使用向量,则可以做到这一点,由于它们的方法更容易处理。

int n,x;
std::cin>>n>>x;
std::vector<int*> myVec;
int* row=new int[n];
for(int i=0;i<n;i++)
    std::cin>>row[i];
myVec.push_back(row);
//do this for all your rows;
myVec.erase(myVec.begin(),myVec.end()+x); //delete first x rows;
//you can play with the line above to delete lines in a range or sth

【讨论】:

【参考方案2】:

还有其他方法可以完成您想做的任务,但假设我们坚持您在问题中讨论的方式。

如果你删除了某一行,你需要记住你删除了哪一行,并确保不再访问它。

为此,您可以维护一个标志数组,其大小等于行数。 flags一开始都是0。

示例 - 如果二维数组共有 10 行,则

int flag[rows] = 0;

删除某行时,可以将该行的flag值改为1。

示例 - 如果我们删除第 4 行,那么

flag[3] = 1;

之后,当你必须遍历二维数组时,你可以跳过标志值等于 1 的行。

这里是示例代码,由我修改:

#include <iostream>
using namespace std;


void printArray(int **matchedIndicesArray,int flag[], int rows, int cols)

    for(int i=0; i<rows; i++)
    
    if(flag[i]==1)    //if flag for the row is 1, that means it is deleted, and so we skip it
    
      continue;
    
        for(int j=0; j<cols; j++)
        
            cout<<matchedIndicesArray[i][j]<<" ";
        
        cout<<endl;
    
    cout<<endl;


void clearMemorySome(int **matchedIndicesArray, int flag[], int rows)


  for(int i = 0; i < rows/2; i++)  //here I chose to delete half the rows
  
    delete [] matchedIndicesArray[i];
    flag[i] = 1;   //to remember which row has been deleted, we change the value of flag to 1
  
  return;
  //delete [] matchedIndicesArray;   //this is commented out because we are only deleting certain rows at a time



int main()

  // Program having 10 * 3 = 30 elements

  int rows = 10;
  int **matchedStagesMatrix;
  matchedStagesMatrix = new int*[rows];

  int cols = 3;

  int flag[rows]=0;    //initially the flag value for every row is 0

  for(int i = 0; i < rows; i++)
  
    matchedStagesMatrix[i] = new int[cols];
    for (int j = 0; j < cols; j++)
    
      matchedStagesMatrix[i][j] = 1;
    
  

  cout<<"The 2D array before half of the rows are deleted\n";
  printArray(matchedStagesMatrix, flag, rows, cols);

  clearMemorySome(matchedStagesMatrix, flag, rows);
  cout<<"The 2D array after half of the rows are deleted\n";
  printArray(matchedStagesMatrix, flag, rows, cols);

  return 0;

以上代码的输出为:

删除一半行之前的二维数组

1 1 1 1 1 1

1 1 1

1 1 1

1 1 1

1 1 1

1 1 1

1 1 1

1 1 1

1 1 1

删除一半行后的二维数组

1 1 1

1 1 1

1 1 1

1 1 1

1 1 1

【讨论】:

由于我们根本没有使用delete [] matchedIndicesArray,我们确定内存被有效且正确地释放了吗?我的意思是,我们只是删除行,而不是包含行的数组,对吧? 是的。在使用指针构造的二维数组中,我们首先删除指向行的指针,然后删除主指针。因为,这里我们没有删除所有指向行的指针,所以我们不能删除主指针。但是一旦删除所有行,您也可以删除主指针。您可以通过检查所有标志是否为 1 来实现这一点,如果是,则必须删除主指针。 那么有没有办法在删除所有行后删除主指针,因为我尝试这样做并且它给出了双重释放或损坏错误。这可能是什么原因? 您可以在删除最后剩余的行后立即删除主指针。我试过了,它有效。为此,您必须跟踪剩余的行。如果remaining_rows==1,那么删除该行后,还必须删除主指针。

以上是关于仅在一定限度内释放 2D 指针数组的内存的主要内容,如果未能解决你的问题,请参考以下文章

C语言中 内存消亡 指向她的指针就一定消亡或成了空指针为啥是错的啊

释放分配给 void 指针数组的内存

怎么用new定义一个类数组,并且释放内存

释放内存触发断点及数组指针的NULL初始化

使用 mmap() 为 2D 数组初始化共享内存,是不是还需要为后续指针映射内存?我应该改用 shm 吗?

如何在C中释放指向结构的指针数组?