This program must raise the number two to a power that the user enters

20 Views Asked by At
Warning C6385   Reading invalid data from 'result'. 21  
Warning C6386   Buffer overrun while writing to 'result'. 12    
Warning C6385   Reading invalid data from 'number'. 58

When raised to a power higher than 3 biological errors.
#include <iostream>
    #include <string>
    using namespace std;

Column multiplication function. First and second warning is here.

void MultiplyArrays(int* ar1, int* len1, int* ar2, int len2) {
        int resultLen = *len1 + len2;
        int* result = new int[resultLen]();
        for (int i = *len1-1; i > -1; --i) {
            int carry = 0;
            for (int j = len2-1; j > -1; --j) {
                int tempSum = result[i + j + 1] + ar1[i] * ar2[i] + carry;
                result[i + j + 1] = tempSum % 10;
                carry = tempSum / 10;
            }
            result[i] += carry;
        }
        int i = 0;
        while (i<resultLen && result[i]==0)
            ++i;
        for (int j = 0; j < i; j++) {
            result[j] = result[j + i];
            --resultLen;
        }
        *len1 = resultLen;
        for (int i = 0; i < resultLen; i++) {
            ar1[i] = result[i];
        }
        delete[] result;
    }

Recursive exponentiation function.

void RaisePowerTwo(int* len, int* array, int power) {
        if (power == 1)
            array[0] = 2;
        else if (power % 2 == 1) {
            RaisePowerTwo(len, array, power - 1);
            int* timeAr = new int[1];
            timeAr[0] = 2;
            MultiplyArrays(array, len, timeAr, 1);
            delete[] timeAr;
        }
        else if (power % 2 == 0) {
            RaisePowerTwo(len, array, power / 2);
            MultiplyArrays(array, len, array, *len);
        }
    }

Main function. Third warning is here

 int main() {
        int n;
        cin >> n;
        int length = 1;
        int* number = new int[length]();
        RaisePowerTwo(&length, number, n);
            for (int i = 0; i < length; ++i)
            cout << number[i];
            delete[] number;
            return 0;
        }

Please help, I've been struggling with this problem for two weeks now. Only today I thought of asking a question on Stask Overflow, this is my first question.

1

There are 1 best solutions below

0
trincot On

There are a few other bugs, but the main issue is that you copy a longer array into a shorter array, and thereby write data outside the range of the shorter array. It happens in this piece of code in MultiplyArrays:

    *len1 = resultLen;
    for (int i = 0; i < resultLen; i++) {
        ar1[i] = result[i];
    }

Here ar1 has "only" a size of *len1 (before it is overwritten by resultLen), while you are writing to ar1[resultLen-1] which can be an out-of-range index for ar1. Realise that this ar1 is the number array that you defined in main and can only hold one integer. You need to allocate memory for the growing array.

In C++ you should use vector for this purpose.

Some of the other issues are:

  • ar2[i] is wrong. The right index to use is j.
  • for (int j = 0; j < i; j++) { is a wrong. It doesn't take into account how many values there are in the result array.
  • Don't use using namespace std

Here is a correction, using vector:

#include <iostream>
#include <vector>

std::vector<int> MultiplyArrays(std::vector<int> v1, std::vector<int> v2) {
    std::vector<int> result(v1.size() + v2.size(), 0);
    for (int i = v1.size() - 1; i > -1; --i) {
        int carry = 0;
        for (int j = v2.size() - 1; j > -1; --j) {
            // index issue
            int tempSum = result[i + j + 1] + v1[i] * v2[j] + carry;
            result[i + j + 1] = tempSum % 10;
            carry = tempSum / 10;
        }
        result[i] += carry;
    }
    while (result[0] == 0)
        result.erase(result.begin());
    return result;
}

std::vector<int> RaisePowerTwo(int power) {
    if (power == 0) { // We can use 0 as base case
        std::vector<int> v = {1};
        return v;
    }
    else if (power % 2 == 1) {
        std::vector<int> two = {2};
        return MultiplyArrays(RaisePowerTwo(power - 1), two);
    }
    else { // No need for condition here
        std::vector<int> root = RaisePowerTwo(power / 2);
        return MultiplyArrays(root, root);
    }
}

int main() {
    int n;
    std::cin >> n;
    std::vector<int> number = RaisePowerTwo(n);
    for (int val : number)
        std::cout << val;
    return 0;
}