2

我觉得我错过了一些明显的东西,我无法弄清楚。基本上,信息似乎正确地存储在第一个 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;
}
4

3 回答 3

4

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

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

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

于 2013-10-16T14:51:04.017 回答
1

Assuming that you do not want to use collections because you are completing a learning exercise, here is what you should keep in mind: when you create an array dynamically, it's best to find out how many elements it is going to have upfront, then allocate it once, fill it with data, use it, and de-allocate the result.

For that to work you need to separate your first loop into two loops - one that counts the digits, and another one that fills in the array with the digits that you find. The allocation should happen after the first loop and before the second loop:

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;
于 2013-10-16T14:52:31.440 回答
0

如果您希望在获得更多数字时调整数组大小,请尝试此操作。这个版本最初有 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++ 移动到循环结束,最后一个版本是错误的。

于 2013-10-16T15:02:56.820 回答