【问题标题】:c++ dynamic memory allocation for arraysc++ 为数组分配动态内存
【发布时间】:2013-10-16 14:46:04
【问题描述】:

我觉得我错过了一些明显的东西,我无法弄清楚。 基本上,信息似乎正确地存储在第一个 for 循环中。但是,当我在第二个 for 循环中将其打印出来时,它只有垃圾值。我错过了什么?我对此比较陌生

bignum::bignum(const string &digits)
{
    int length = digits.length();
    ndigits = 0;    

    for (int i = 0; i < length; i++)
    {
        if(isdigit(digits[i]))
        {
            ndigits++;
            digit = new int[ndigits];
            int tmpInt = digits[i] - '0';
            digit[i] = tmpInt;
        }
        if(isalpha(digits[i]))
        {
            break;
        }
        cout <<"step "<< i << " " << digit[i] << endl;
    }

    for (int i = 0; i < ndigits; i++)
    {
        cout << digit[i] << " ";
    }
    cout << endl;
    cout << "digits" << ndigits << endl;
    cout << endl;
}

【问题讨论】:

  • 你正在疯狂地泄漏内存。
  • @chris 我有一个数字数组的析构函数
  • 没关系,您在循环内根据条件调用new。我看不出你如何为每个new [] 打电话给delete[]
  • 现在我明白我在做什么了.. 谢谢!

标签: c++ memory dynamic integer allocation


【解决方案1】:

每次isdigit(digits[i]) 条件为true 时,您都在动态分配digit。 因此,每当您找到一个数字时,您就会再次为digit 分配内存,而有关先前数字的信息将丢失。此外,还有内存泄漏。

您应该在for 循环开始之前分配一次digit,并计算您找到的位数并将找到的位数存储在digit 中。

此外,您应该在完成任何动态分配的内存后释放它,以便可以重复使用。

【讨论】:

  • 另外,您应该考虑不要直接使用动态分配的内存,而是使用例如一个向量或智能指针;)
  • @nyarlathotep 是的,确实
  • @nyarlathotep 相信我,如果可以的话,我会使用向量,但这是一个类,它需要动态分配的数组。
【解决方案2】:

假设您不想使用集合,因为您正在完成一个学习练习,以下是您应该记住的:当您动态创建一个数组时,最好预先找出它将有多少元素,然后分配一次,用数据填充,使用它,然后释放结果。

为此,您需要将第一个循环分成两个循环 - 一个计算数字,另一个用您找到的数字填充数组。分配应该发生在第一个循环之后和第二个循环之前:

ndigits = 0;    
// First, you need to count the digits
for (int i = 0; i < length; i++)
{
    if(isdigit(digits[i]))
    {
        ndigits++;
    }
    if(isalpha(digits[i]))
    {
        break;
    }
}
// Next, allocate the array for your digits
int *digit = new int[ndigits];
int *dp = digit;
// Now go through the string again, and add digits to the newly allocated array
for (int i = 0; i < length; i++)
{
    if(isdigit(digits[i]))
    {
        (*dp++) = (digits[i] - '0');
    }
    if(isalpha(digits[i]))
    {
        break;
    }
}
... // Use your digit[] array here...
// Once you are done, free the array
delete[] digit;

【讨论】:

    【解决方案3】:

    如果您希望在获得更多数字时调整数组大小,请尝试此操作。这个版本最初有 10 个空间,当数字 11 出现时将大小增加 10,依此类推。创建一个新数组,并将旧数据复制到其中。旧数位数组被删除,其指针被新版本替换。

    此方法在某些情况下可能会很慢(因为旧的已满时复制到新的更大),但如果您通常少于 10 位数应该没问题。如果您通常有超过 10 个,请使用更大的初始数字。

    int digits_max = 10;
    int digits_pos = 0;
    int *digit = new int[digits_max];
    

    ...

    if(isdigit(digits[i])) {
        if (digits_pos == digits_max) {
            int new_max = digits_max + 10;
            int *digit_tmp = new int[new_max];
    
            // Copy from old array to new
            for (int i = 0; i < digits_max; i++) {
                digit_tmp[i] = digit[i];
            }
    
            delete[] digit; // Free old memory, or your RAM gets full
    
            digit = digit_tmp;
            digits_max = new_max;
        }
    }
    else { // Always break if not int
        break;
    }
    
    int tmpInt = digits[i] - '0';
    digit[digits_pos] = tmpInt;
    digits_pos++;
    

    在退出之前(或者当你使用完数字数组之后),你应该删除它:

    delete[] digit;
    

    编辑:将 digits_pos++ 移到循环末尾,最后一个版本是错误的。

    【讨论】:

      猜你喜欢
      • 2014-12-09
      • 2021-04-02
      • 1970-01-01
      • 2023-03-17
      • 2021-07-17
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多