Reputation: 16126
i need to fill in the int[] array in C++ from zero to number defined by variable, but ISO C++ forbids variable length array... How to easily fill in the array? Do i need to allocate/free the memory?
int possibilities[SIZE];
unsigned int i = 0;
for (i = 0; i < SIZE; i++) {
possibilities[i] = i;
}
btw. if you would ask - Yes, i need exactly standard int[] arrays, no vectors, no maps etc.
Upvotes: 8
Views: 41974
Reputation: 89224
Since C++ 23, ranges::iota
can be used to initialize an array or other container with increasing values.
#include <numeric>
// only used for output:
#include <algorithm>
#include <iterator>
#include <iostream>
int main() {
int arr[5]; // also works the same for std::array<int, 5>, std::vector<int>, etc
std::ranges::iota(arr, 0); // fills arr with increasing integers starting from 0
std::ranges::copy(arr, std::ostream_iterator<int>(std::cout, " ")); // 0 1 2 3 4
}
Alternatively, since C++ 11, std::begin
and std::end
can be used to get iterators to plain arrays to pass to std::iota
.
#include <numeric> // for iota
#include <iterator> // for begin and end
#include <iostream> // output
int main() {
int arr[5];
std::iota(std::begin(arr), std::end(arr), 0);
for (int x : arr) std::cout << x << ' ';
std::cout << '\n';
}
Upvotes: 0
Reputation: 1
Assuming SIZE
is a constant expression and you're allowed to use std::array
, you can create a function template that will allow you to do this at compile time. Note from C++17, std::array<T, N>::begin
is constexpr
so that you can do all this at compile time.
template<std::size_t N> std::array<int, N> constexpr make_array()
{
std::array<int, N> tempArray{};
int count = 0;
for(int &elem:tempArray)
{
elem = ++count;
}
return tempArray;
}
int main()
{
const int SIZE = 8;
//-------------------------------V-------->number of elements
constexpr auto arr = make_array<SIZE>();
//lets confirm if all objects have the expected value
for(const auto &elem: arr)
{
std::cout << elem << std::endl; //prints 1 2 3 4 5 6 7 8 with newline in between
}
}
But prior to C++17, std::array<T, N>::begin
was not constexpr, we will need to modify the above example slightly for C++11 as shown below:
template<std::size_t N> std::array<int, N> make_array()
{
std::array<int, N> tempArray{};
int count = 0;
for(int &elem:tempArray)
{
elem = ++count;
}
return tempArray;
}
int main()
{
const int SIZE = 8;
//---------------------VVVV---->number of elements
auto arr = make_array<SIZE>();
//lets confirm if all objects have the expected value
for(const auto &elem: arr)
{
std::cout << elem << std::endl; //prints 1 2 3 4 5 6 7 8 with newline in between
}
}
Upvotes: 0
Reputation: 844
std::generate() can be used with a mutable lambda function to be more concise. The following C++ snippet will place the values 0..9 inclusive in a vector A of size 10 and print these values on a single line of output:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
size_t N = 10;
vector<int> A(N);
generate(A.begin(), A.end(), [i = 0]() mutable { return i++; });
copy(A.begin(), A.end(), ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
}
Upvotes: 0
Reputation: 1090
Simply use a dynamic arrays?
type * pointer;
pointer = new type[number_of_elements];
void main()
{
int limit = 0; // Your lucky number
int * pointer = NULL;
cout << "Please, enter limit number: ";
cin >> n;
pointer = new int[limit+1]; // Just to be sure.
for (int i = 0; i < n; i++)
{
pointer[i] = i; // Another way is: *(pointer+i) = i (correct me if I'm wrong)
}
delete [] pointer; // Free some memory
pointer = NULL; // If you are "pedant"
}
I don't pretend this is the best solution. I hope it helps.
Upvotes: -1
Reputation: 341
In c++11 you can use std::iota and std::array. Example below fills array sized 10 with values from 1 to 10.
std::array<int, 10> a;
std::iota(a.begin(), a.end(), 1);
Edit Naturally std::iota works with vectors as well.
Upvotes: 34
Reputation: 1658
If you have access to boost then you already have access to an incrementing iterator.
#include <vector>
#include <boost/iterator/counting_iterator.hpp>
std::vector<int> possibilities(
boost::counting_iterator<int>(0),
boost::counting_iterator<int>(SIZE));
The counting iterator essentially wraps incrementing a value. So you can automatically tell it the begin and end values and vector will populate itself properly.
As mentioned elsewhere, the resulting vector can be used directly with std::next_permutation.
std::next_permutation(possibilities.begin(),possibilities.end());
Upvotes: 3
Reputation: 41509
You can use the std::generate_n
function:
std::generate_n( myarray, SIZE, increment() );
Where increment
is an object that generates numbers:
struct increment {
int value;
int operator() () { return ++value; }
increment():value(0){}
};
Upvotes: 1
Reputation: 5693
std::vector<int> possibilities;
unsigned int i = 0;
for (i = 0; i < SIZE; i++) {
possibilities.push_back(i);
}
Use std::vector
(you need to include <vector>
)
If you want pass vector to std::next_permutation
you need to write:
std::next_permutation(possibilities.begin(),possibilities.end());
also you can use vector as C style arrays. &vec[0]
returns pointer to C style array.
Upvotes: 2
Reputation: 272467
As you've found, you cannot create a variable-length array on the stack. So your choices are either to allocate it on the heap (introduces memory-management issues), or to use a std::vector
instead of a C-style array:
std::vector<int> possibilities(SIZE);
for (int i = 0; i < SIZE; i++)
{
possibilities[i] = i;
}
If you want to get even more flashy, you can use STL to generate this sequence for you:
// This is a "functor", a class object that acts like a function with state
class IncrementingSequence
{
public:
// Constructor, just set counter to 0
IncrementingSequence() : i_(0) {}
// Return an incrementing number
int operator() () { return i_++; }
private:
int i_;
}
std::vector<int> possibilities(SIZE);
// This calls IncrementingSequence::operator() for each element in the vector,
// and assigns the result to the element
std::generate(possibilities.begin(), possibilities.end(), IncrementingSequence);
Upvotes: 17
Reputation: 1979
it should be help u man
int* a = NULL; // Pointer to int, initialize to nothing.
int n; // Size needed for array
cin >> n; // Read in the size
a = new int[n]; // Allocate n ints and save ptr in a.
for (int i=0; i<n; i++) {
a[i] = 0; // Initialize all elements to zero.
}
. . . // Use a as a normal array
delete [] a; // When done, free memory pointed to by a.
a = NULL; // Clear a to prevent using invalid memory reference
Upvotes: -2
Reputation: 22149
If you make SIZE a constant (macro or const
), you can use it to specify the size of your static array. If it is not possible to use a constant, for example you are reading the intended size from outside the program, then yes you will need to allocate the memory.
In short, if you don't know the size at compile time you probably need to allocate the memory at runtime.
Upvotes: 0