0

Having some problems with dynamic memory allocation..

Here's the code:

#include <iostream>
using namespace std;

void inputarray(int* x, int n) {
    cout << "Input " << n << " numbers\n";
    for (int i = 0; i < n; i++) {
        cin >> x[i];
    }
}

void inputRandArray(int* x, int n) {
    srand(time(0));
    for (int i = 0; i < n; i++)
        x[i] = rand() % 100;
}


void insert(int* x, int& n, int pos, int value) {
    int* p = (int*)realloc((int*)x, sizeof(int) * (n+1));
    n++;
    if (!p) {
        cout << "Oshibka pamyati!";
        return;
    }
    else {
        x = p;
    }
    for (int i = n-1; i > pos; i--) {
        x[i] = x[i - 1];
    }
    x[pos] = value;
}

void outArray(int* x, int n) {
    cout << "Massiv " << n << " chisel, n = " << n << "\n";
    for (int i = 0; i < n; i++) {
        cout << x[i] << " ";
    }
    cout << "\n";
}

void erase(int* x, int& n, int pos) {
    
    for (int i = pos; i < n-1; i++) {
        x[i] = x[i + 1];
    }
    int* p = (int*)realloc((int*)x, sizeof(int) * (n-1));
    n--;
    
    if (!p) {
        cout << "Oshibka pamyati!";
        return;
    }
    else {
        x = p;
    }
}

bool prime(int n) {
    if (n < 2) return false;
    if (n == 2) return true;
    if (n % 2 == 0) return false;
    for (int i = 3; (i * i) <= n; i += 2) {
        if (n % i == 0) return false;
    }
    return true;
}

int findMinimumPrime(int* a, int n, int& pos) {
    // Find minimum prime number
    int minNum = INT32_MAX;
    for (int i = 0; i < n; i++) {
        if (prime(a[i])) {
            if (a[i] < minNum) {
                minNum = a[i];
                pos = i;
            }
        }
    }
    return minNum;
}


int findMaximumPrime(int* a, int n, int& pos) {
    // Find maximum prime number
    int maxNum = INT32_MIN;
    for (int i = 0; i < n; i++) {
        if (prime(a[i])) {
            if (a[i] > maxNum) {
                maxNum = a[i];
                pos = i;
            }
        }
    }
    return maxNum;
}

int countPrime(int* a, int n) {
    int count = 0;
    for (int i = 0; i < n; i++) {
        if (prime(a[i])) {
            count++;
        }
    }
    return count;
}

void fillArray(int* a, int& n, int* b, int& n_b) {
    int pos = -1;
    int minPrime = findMinimumPrime(a, n, pos);
    b[0] = minPrime;
    erase(a, n, pos);
    int primeAmount = countPrime(a, n);
    cout << endl;
    outArray(a, n);
    outArray(b, n_b);
    cout << endl;
    for (int i = 0; i < primeAmount; i++) {
        pos = -1;
        int maxPrime = findMaximumPrime(a, n, pos);
        cout << endl << n << n_b << endl;
        insert(b, n_b, 1, maxPrime);
        erase(a, n, pos);
        cout << endl << n << n_b << endl;
    }

}

void editArray(int* a, int& n) {
    int pos = -1;
    findMinimumPrime(a, n, pos);
    erase(a, n, pos);
}

int countDivisors(int* a, int& n) {
    int counter = 0;
    for (int i = 0; i < n; i++) {
        int count = 0;
        for (int j = 1; j <= a[i]; j++) {
            if (a[i] % j == 0) count++;
        }
        if (count > 3) counter++;
    }
    return counter;
}

int main()
{
    cout << "Variant 28" << endl;
    int n = 1;
    cin >> n;
    int* arr;
    arr = (int*)malloc(n * sizeof(int));
    inputRandArray(arr, n);
    int* newArr;
    newArr = (int*)malloc(1 * sizeof(int));
    int n2 = 1;
    cout << "Iskhodniy massiv" << endl;
    outArray(arr, n);
    fillArray(arr, n, newArr, n2);
    cout << "Resultat (punkt 1)" << endl;
    outArray(newArr, n2);
    cout << "Resultat (punkt 2)" << endl;
    editArray(newArr, n2);
    outArray(newArr, n2);
    cout << "Resultat (punkt 3)" << endl;
    cout << countDivisors(arr, n);
    free(arr);
    free(newArr);
}

It executes some operations (moves prime numbers in rising sequence to second array, then removes the minimal number, then counts all the numbers in original array with more than 3 divisors).

However sometimes program works fine, and sometimes it crashes midway hinting to heap corruption, which I cannot find (I suppose it's somewhere in insert-erase functions). Using malloc-realloc is mandatory (university task).

trincot
  • 317,000
  • 35
  • 244
  • 286
danshat
  • 25
  • 9
  • 1
    You pass the variable `x` by value in `void insert(int* x, int& n, int pos, int value) {` so that if you change what `x` points to `x=p;` the code that calls insert() will not see the change at all. It will operate on the `x` that it passed to insert(). You repeat this mistake in all functions that need to reallocate the dynamic array. – drescherjm Mar 04 '22 at 13:28
  • You're most likely writing beyond the `arr` array somewhere. – Jabberwocky Mar 04 '22 at 13:31
  • 3
    @danshat `void foo(int *x) { x = new int; } int main() { int *p = nullptr; foo(p); }` -- You will see that `p` is still `nullptr` after calling `foo`. – PaulMcKenzie Mar 04 '22 at 13:35
  • 3
    ***However sometimes program works fine, and sometimes it crashes midway hinting to heap corruption*** When you get time google the term: Undefined Behavior – drescherjm Mar 04 '22 at 13:36
  • 3
    And BTW, your school is teaching `C`, not C++. If the name of the course has `C++` in its name, you're being cheated. – PaulMcKenzie Mar 04 '22 at 13:37

0 Answers0