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];
}
}
CodePudding user response:
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 ;
}
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.
CodePudding user response:
When you write while (i <= n && j <= m)
you might get one item after the end of the array.
Also, use dynamic allocation if you want the arrays to hold as many items as user wants.
int *a = new int[n];