-2

I'm trying to combine two sorted arrays and when I compare two of the elements, each one from one of the two arrays, I get the warning " Using uninitialized memory 'x' ".

Here is my input:

5 
1 3 5 7 9 
5 
2 4 6 8 10

And the output:

-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993460-858993460

Here is my code:

#include <iostream>

int main() {
    int n, m;
    int a[100], b[100], c[201];
    std::cin >> n;
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
    } 
    std::cin >> m;
    for (int i = 0; i < m; i++) {
        std::cin >> b[i];
    } 
    int i = 0; int j = 0; int k = 0;
    while (i <= n && j <= m) {
        if (a[i] > b[j]) {
            c[k] = a[i];
            i++;
        }
        else {
            c[k] = b[j];
            j++;
        }
        k++;
    }
    while (i < n) {
        for (int p = k; p < n; p++) {
            c[p] = a[i];
        }
    }
    while (j < m) {
        for (int p = k; p < m; p++) {
            c[p] = b[j];
        }
    }
    for (int i = 0; i < k; i++) {
        std::cout << c[k];
    }
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Karlson
  • 1
  • 1
  • 2
    `while (i <= n && j <= m)` is not correct -- you will read 1 past the end of what you input (array index starts at 0, the last valid input was index `n-1`) – M.M Feb 04 '23 at 21:19
  • It's a bit strange that your question's title is more descriptive than the question's body. You might want to review [ask]. – JaMiT Feb 04 '23 at 23:03
  • *"'Using uninitialized memory' [...] even though I read all the elements"* -- The "even though" phrasing suggests a contradiction, but this is more of a confirmation. The warning is because you are reading more than you wrote. For a contradiction, you should assert that you **wrote** all the elements. – JaMiT Feb 04 '23 at 23:05

1 Answers1

0

The condition of the while loop

while (i <= n && j <= m) {
    if (a[i] > b[j]) {
        c[k] = a[i];
        i++;
    }
    else {
        c[k] = b[j];
        j++;
    }
    k++;
}

is invalid. If for example the array a has n initialized elements then the valid index for the array is in the range [0, n). Using the expression a[n] results either in accessing memory outside the array a or in reading an uninitialized element of the array.

So you need to write

while (i < n && j < m) {
    if (a[i] > b[j]) {
        c[k] = a[i];
        i++;
    }
    else {
        c[k] = b[j];
        j++;
    }
    k++;
}

Also bear in mind that usually only when an element of the second container (array) is greater than a corresponding element of the first container (array) then it is written in the result container.

That is the if statement should look like

    if ( a[i] < b[j] ) {
        c[k] = b[j];
        j++;
    }
    else {
        c[k] = a[i];
        i++;
    }

if you want to merge arrays in the descending order.

Or

    if ( b[j] < a[i] ) {
        c[k] = b[j];
        j++;
    }
    else {
        c[k] = a[i];
        i++;
    }

if you want to merge arrays in the ascending order. And you are going to merge your arrays in the ascending order.

These while loops

while (i < n) {
    for (int p = k; p < n; p++) {
        c[p] = a[i];
    }
}
while (j < m) {
    for (int p = k; p < m; p++) {
        c[p] = b[j];
    }
}

can be infinite loops because neither the variable i nor the variable j are being changed within the loops. At least they try to assign the same elements a[i] and b[j] to elements of the array c. And moreover the value of the variable k can be greater than the value of the variable n and greater than the value of the variable m though either array a or the array b has elements that were not yet copied in the array c.

Instead you should write

while (i < n) c[k++] = a[i++];
while (j < m) c[k++] = b[j++];

Pay attention to that you should check that entered values of the variables n and m are not greater than 100.

And there is no great sense to declare the array c with 201 elements instead of 200 elements

int a[100], b[100], c[201];

Pay attention that there is standard algorithm std::merge declared in header <algorithm> that you could use. Here is a demonstration program

#include <iostream>
#include <iterator>
#include <algorithm>

int main()
{
    int a[] = { 1, 3, 5, 7, 9 };
    int b[] = { 0, 2, 4, 6, 8, 10 };
    int c[std::size( a ) + std::size( b )];

    std::merge( a, a + std::size( a ), b, b + std::size( b ), c );

    for (const auto item : c)
    {
        std::cout << item << ' ';
    }
    std::cout << '\n';
}

The program output is

0 1 2 3 4 5 6 7 8 9 10

In the program there are not used standard functions std;:begin and std::end becuase in your program you are using sub-arrays. Though you could write in your program for example

    std::merge( std::begin( a ), std::next( std::begin( a ), n ),
                std::begin( b ), std::next( std::begin( b ), m ),  
                std::begin( c ) );  

Instead of the arrays with predefined sizes you could use standard container std::vector<int> that allows to specify an arbitrary number of elements. With objects of the container you can use the same subscript operator.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335