1

I have a variable k of type int to set the length of a dynamically allocated int array:

int *Numbers = new int[k];

But because of this I cannot iterate over the array, I get an error:

"no matching begin function was found required for this range-based for statement"

I also cannot get the length of the array using size();

Here's the complete code:

#include <iostream>
using namespace std;
int main()
{
    int b, k;
    cin >> b >> k;
    int *Numbers = new int[k];
    for (int i : Numbers) {// (There is a error)
    }
    for (int i = 0; i < size(Numbers); i++) {

    }
}
anastaciu
  • 23,467
  • 7
  • 28
  • 53
undefined
  • 11
  • 4
  • 3
    Use `std::vector` and your problem, and many more, are solved. Allocations with `new[]` do not have an intrinsic size, you must store that separately. – tadman Aug 27 '20 at 07:30

7 Answers7

1

Prefer using a std::vector instead of a std::array. (Like @tadman mentioned.)

Here is your code using std::vector instead:

#include <iostream>
#include <vector>

int main()
{
    int b, k;

    std::cin >> b >> k;

    std::vector<int> Numbers(b,k); // Fills the vector "Numbers" with nth number of elements with each element as a copy of val.
    for (int i : Numbers) 
        std::cout << i << std::endl;
        
    for (int i = 0; i < Numbers.size(); i++) 
        std::cout << Numbers[i] << std::endl;
        
    
     return 0;
}

Say I want 10 elements with the number 5.

Output:

10
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5

Also consider not using namespace std;.

Geno C
  • 1,401
  • 3
  • 11
  • 26
1

The simple and recommended solution is to use std::vector, however if you really want a dynamically allocated array and to use iterator like features on it, you can use iterator_range from boost library, which allows you to create an iterator range for it thus making it usable in range based for loops and in functions like std::size.

Live demo

#include <iostream>
#include<boost/range.hpp>

int main()
{
    int k = 5;
    int *Numbers = new int[k]{1,4,5,7,8};
    
    auto arr = boost::make_iterator_range(Numbers, Numbers + k); 

    for (int i : arr) {  //range based loop
        std::cout << i << " ";
    }
    
    std::cout << std::endl << "Size: " << arr.size();  //print size
    //or std::size(arr);
}

Output:

1 4 5 7 8 
Size: 5
anastaciu
  • 23,467
  • 7
  • 28
  • 53
0

Range-based for loops work with arrays, but not work with pointers. The Actual issue is that arrays is actually a pointer and not an array.try to use simple array.

Programmer_3
  • 522
  • 5
  • 18
0

Using pointers is problematic for many reasons. The simple solution to your problem is to use a vector

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    int b, k;
    cin >> b >> k;
    vector<int> Numbers(k);
    for (int i : Numbers) {
         cout << i << endl;
    }
    for (int i = 0; i < Numbers.size(); i++) {
         cout << Numbers[i] << endl;
    }
}
john
  • 85,011
  • 4
  • 57
  • 81
0

C array does not have default iterator and thus there is no begin() and end() functions that are used to iterate over array when you use statment like this:

for (int i : Numbers)

You can check range-for reference:

range_expression - any expression that represents a suitable sequence (either an array or an object for which begin and end member functions or free functions are defined, see below) or a braced-init-list.

Nikola
  • 125
  • 1
  • 8
0

Okay, so since the dynamic array does not have a default iterator, do not use the for-each loop, instead consider using the regular for loop. Also, mind the the size function will not work for an array (or dynamic array) and you need to remember the size, since it's not possible to get the size from the pointer only. Hence, this code would work:

#include <iostream>
using namespace std;
int main()
{
    int b, k;
    cin >> b >> k;
    int *Numbers = new int[k];
    const int SIZE = k;
    for (int i = 0; i < SIZE; i++) {
        cout << i << ' ';
    }
} 
  • `std::size` works with array arguments (except for VLA's, which are illegal in C++), just not for pointers. – anastaciu Aug 27 '20 at 16:13
0

You need to dereference *Numbers by using the * if you want to iterate over the array because *Numbers is a pointer to an integer which points to the first element of your array.For Example :

#include <iostream>

using namespace std;

int main()
{
    int k = 10;
    int *numbers = new int[k];
     
    //filling the array 
    for(int i = 0 ; i < k ; ++i) {
        *(numbers + i) = i ;
    }
    
    //output array element
    for(int i = 0 ; i < k ; ++i) {
        cout << numbers + i << " is the address of "<<*(numbers + i) << endl;
    }

    return 0;
}

The output is :

0x6f1750 is the address of 0
0x6f1754 is the address of 1
0x6f1758 is the address of 2
0x6f175c is the address of 3
0x6f1760 is the address of 4
0x6f1764 is the address of 5
0x6f1768 is the address of 6
0x6f176c is the address of 7
0x6f1770 is the address of 8
0x6f1774 is the address of 9

Unfortunatly, you can't get the size of your array with *Numbers because it's not an array but a pointer.

PopJoestar
  • 462
  • 1
  • 4
  • 10