Getting an error while initializing the size of an array

I have a following function "arrayMerger" and I want to add up size of two arrays and then assign its size to another array but I got an error as "expression must have a constant value". Can someone please explain why this error is occurring.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

using namespace std;

void arrayMerger(int *arr1, int *arr2, int size1, int size2)
{
	int size = size1 + size2;
	int arr[size];
}

int main()
{
	int arr1[] = { 7,2,9,1 };
	int arr2[] = { 8,1,5,3,4,0 };
	int size1 = sizeof(arr1) / sizeof(int);
	int size2 = sizeof(arr2) / sizeof(int);
	arrayMerger(arr1, arr2, size1, size2);

	return 0;
}
Arrays in C++ have to be a compile-time constant value.
What you're attempting to do simply isn't standard C++.

Instead of arrays, you can use vectors, which allow for dynamic-size initialization, and resizing at runtime.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <vector>

using namespace std;

vector<int> arrayMerger(const vector<int>& v1, const vector<int>& v2)
{
    // (Could be done with iterators as well)
    vector<int> merged(v1.size() + v2.size());
    
    for (size_t i = 0; i < v1.size(); i++)
    {
        merged[i] = v1[i];   
    }
    for (size_t i = v1.size(); i < v1.size() + v2.size(); i++)
    {
        merged[i] = v2[i - v1.size()];
    }
    
    return merged;
}

/// overload << operator to allow for printing vec to cout.
std::ostream& operator<<(std::ostream& os, const std::vector<int>& vec)
{
    for (size_t i = 0; i < vec.size(); i++)
    {
        os << vec[i] << ' ';   
    }
    return os;
}

int main()
{
	vector<int> v1 = { 7,2,9,1 };
	vector<int> v2 = { 8,1,5,3,4,0 };
	
	vector<int> v3 = arrayMerger(v1, v2);

	cout << v1 << '\n';
	cout << v2 << '\n';
	cout << v3 << '\n';

	return 0;
}


7 2 9 1 
8 1 5 3 4 0 
7 2 9 1 8 1 5 3 4 0 
 


Edit: And shamelessly copied from SO, as I mentioned earlier, you can also use iterators to make arrayMerger simpler
https://stackoverflow.com/questions/3177241/what-is-the-best-way-to-concatenate-two-vectors

1
2
3
4
5
6
7
8
9
vector<int> arrayMerger(const vector<int>& v1, const vector<int>& v2)
{
    vector<int> merged;
    merged.reserve( v1.size() + v2.size() ); // preallocate memory
    merged.insert( merged.end(), v1.begin(), v1.end() );
    merged.insert( merged.end(), v2.begin(), v2.end() );

    return merged;
}
Last edited on
+1 for Ganado’s answer — it is the correct answer.

That said, what you seem to be trying to do is still a compile-time issue, for which you can use arrays:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <ciso646>
#include <iostream>

using namespace std;

// Here is a very pretty version of the function to get your (compile time) array size.
// (You can find the Standard Library equivalent in <type_traits>, but it’s ugly.)
//
// Notice the template meta-magic to get the unnamed argument array’s size.
//
// This replaces the "sizeof(arr) / sizeof(arr[0])" trick, BTW.
//
template <typename T, size_t N>
constexpr size_t array_size( const T (&)[ N ] )
{
  return N;
}

// To combine the (extant) arrays, you can use the same kind of magic to
// handle their sizes.
//
template <typename T, size_t N1, size_t N2, size_t N>
void merge_arrays( const T (&arr1)[ N1 ], const T (&arr2)[ N2 ], T (&result)[ N ] )
{
  // First, a sanity check (performed at compile time), just to make sure that 
  // you didn't goof and give a too-small array to the function.
  static_assert( (N1 + N2) <= N );

  // I am unsure what you mean by "merge" the arrays. 
  // In CS parlance, merging typically means a sorted-to-sorted combine:
  size_t n = 0, n1 = 0, n2 = 0;
  while ((n1 < N1) and (n2 < N2)) 
  {
    if (arr1[n1] < arr2[n2]) result[n++] = arr1[n1++];
    else                     result[n++] = arr2[n2++];
  }
  while (n1 < N1) result[n++] = arr1[n1++];
  while (n2 < N2) result[n++] = arr2[n2++];
}


int main()
{
  // The initial arrays...
  int arr1[] = { 1,2,7,9 };     //{ 7,2,9,1 };      // Since "merge" means input is sorted...
  int arr2[] = { 0,1,3,4,5,8 }; //{ 8,1,5,3,4,0 };  // ...the input must therefore be sorted

  // Declare our new array with a concrete size
  // -- which we get from the above two arrays’ sizes
  int arr3[ array_size( arr1 ) + array_size( arr2 ) ];

  // Runtime merge of the array content
  merge_arrays( arr1, arr2, arr3 );

  // Print the results for the user
  for (auto x : arr3)
    cout << ' ' << x;
  cout << '\n';
}

Hope this helps clear some things up about arrays.

Again, prefer to use std::vector for dynamic content.
The standard library has std::merge() https://en.cppreference.com/w/cpp/algorithm/merge
and std::size() (C++17) https://en.cppreference.com/w/cpp/iterator/size

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>

template < typename T, std::size_t N1, std::size_t N2 >
std::vector<T> merge( const T (&a1)[N1], const T (&a2)[N2] )
{
    std::vector<T> merged ;
    std::merge( std::begin(a1), std::end(a1), std::begin(a2), std::end(a2),
                std::back_inserter(merged) ) ;
    return merged ;
}

template < typename T, std::size_t N1, std::size_t N2 >
std::vector<T> cat( const T (&a1)[N1], const T (&a2)[N2] )
{
    std::vector<T> concat( std::begin(a1), std::end(a1) ) ;
    std::copy( std::begin(a2), std::end(a2), std::back_inserter(concat) ) ;
    return concat ;
}

int main()
{
    const int a1[] = { 1, 2, 7, 7, 9 };
    const int a2[] = { 0, 1, 3, 4, 5, 6, 7, 8 };

    for( int v : merge(a1,a2) ) std::cout << v << ' ' ;
    std::cout << '\n' ;

    int a3[ std::size(a1) + std::size(a2) ] ;
    std::merge( std::begin(a1), std::end(a1), std::begin(a2), std::end(a2), std::begin(a3) ) ;
    for( int v : a3 ) std::cout << v << ' ' ;
    std::cout << "\n\n" ;

    for( int v : cat(a1,a2) ) std::cout << v << ' ' ;
    std::cout << '\n' ;
}

http://coliru.stacked-crooked.com/a/d2f2db8dc1e3c7c8
https://rextester.com/VCLRW58450
Topic archived. No new replies allowed.