仅在一定限度内释放 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循环外的最后一行。
【问题讨论】:
不使用向量吗? 假设,这必须使用指针而不是向量来完成。 您可以使用指针向量来实现这一点,删除会更容易 将表示第一个和最后一个索引的值传递给delete
d,并相应地循环。您需要决定是否执行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语言中 内存消亡 指向她的指针就一定消亡或成了空指针为啥是错的啊