【问题标题】:How do I deallocate cells of a different length from the initial length in a dynamic 2d array?如何在动态二维数组中释放与初始长度不同长度的单元格?
【发布时间】:2013-11-19 05:14:01
【问题描述】:

我正在尝试将名称读入 20 行的二维动态数组,其中名称的长度不受限制。由于引入了超出初始值 10 的新长度,程序最后崩溃并出现“堆损坏”错误。但是,遇到的唯一问题是当我运行循环删除上述单元格时。有谁知道如何删除长度与初始值不同的单元格? (特别是在这种情况下。)我是否需要将数组中的所有单元格设为新长度?附言我不能使用向量,因为这是一项禁止它们的家庭作业。

好的。这是带有@RetiredNinja 建议更改的更新版本。它运行得很好,在我之前测试的任何条件下,我都不再出现“堆损坏”错误。

#include <iostream>

using namespace std;

#include <memory.h>
#include <string.h>                             // will be used once I write the sort and search functions

char * ReadString();

void main ()
{
bool contMain=true;
const long numNames=20;
long nameAc=0;
char ** ppNames, c;
ppNames=new char* [numNames];
char test;

while(contMain && nameAc<numNames)
{
    ppNames[nameAc]=ReadString();
    test=ppNames[nameAc][0];
    if(test=='\0')
    {
        contMain=false;
        break;
    }
    else;
    nameAc++;
}
for(int i=0; i<nameAc; i++)
    cout<<ppNames[i]<<endl;

// deallocation
for(int i=0; i<nameAc; i++)
{
    cout<<i<<endl;
    delete ppNames [i];
}
delete[] ppNames;
}


char * ReadString()
{
long aSize=10;
long numChars (0);
char * pNames;
char * pTemp;
char c;
pNames=new char [aSize+1];

while((c = cin.get()) != '\n')
    {
        if(numChars >= aSize)
        {
            aSize *= 2;
            pTemp = new char[aSize + 1];
            memcpy(pTemp, pNames, numChars);
            delete[] pNames;
            pNames = pTemp;
            cout << "Array size increased to " << aSize << endl;
        }
        pNames[numChars++] = c;
    }
    pNames[numChars] = '\0'; //end of string
    return pNames;
}

【问题讨论】:

  • 函数 ReadString() 本身有很多地方需要改变。例如 pNames = new char[aSize + 1]; pNames = pTemp;这将立即导致内存泄漏。并且意图不明确。可以稍微整理一下代码再发帖吗?

标签: c++ arrays memory dynamic delete-operator


【解决方案1】:

您的大部分代码没有多大意义。您相当随意地分配和删除,通常会撤消您之前仅几行所做的操作。

试试这样的:

char * ReadString()
{
    long aSize = 10;
    long numChars = 0;
    char * pNames;
    char * pTemp;
    char c;
    pNames = new char[aSize + 1];

    while((c = cin.get()) != '\n')
    {
        if(numChars >= aSize)
        {
            aSize *= 2;
            pTemp = new char[aSize + 1];
            memcpy(pTemp, pNames, numChars);
            delete[] pNames;
            pNames = pTemp;
            cout << "Array size increased to " << aSize << endl;
        }
        pNames[numChars++] = c;
    }
    pNames[numChars] = '\0';//end of string
    return pNames;
}

【讨论】:

  • 非常感谢您的帮助,我有几个关于何时删除分配的内存的问题。为什么我不需要在声明 pNames 和 pTemp 后删除它们?另外,你发布的函数会不会导致内存泄漏?
  • 所以,你有两个案例。阵列不需要变得更大的一种。您分配该内存,然后返回指针,以便以后可以将其删除。第二个是当数组增长时,你分配一个两倍大的缓冲区分配给pTemp,从pNames复制数据,删除pNames,然后分配pTemp to pNames`,然后返回它以便稍后删除。跨度>
  • 只要您将一个new 与一个delete 匹配,您就不应该有任何泄漏。像这样的函数的唯一问题是你指望调用它的人稍后删除该内存。
  • 哦,好吧。这现在更有意义了。因此,当我在 main 函数中删除 ppNames 时,它也会删除从 ReadString 以及 pTemp 返回的 pNames,因为它使用的地址与 pNames 相同?
  • 是的,重要的是在某个地方使用指向它的指针删除内存,它不必是同一个指针。
猜你喜欢
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 2014-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多