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.
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.
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);
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());
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.
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){}
};
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.
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;
}
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.
C++17 Version
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
}
}
C++17 demo
C++11 Version
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
}
}
C++11 demo
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.
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
Related
I am learning C++ with experiencein mostly Python, R and SQL.
The way arrays (and vectors which differes somehow from 1d-arrays? and matrices which are 2d-arrays?) work in C++ seems quite different as I cannot specify the size of dimension of the array with an argument from the function.
A toy-example of my goal is some thing like this:
Have a function my_2d_array which takes two arguments M and N and returns a matrix or 2d-array of dimension (MxN) with elements indicating the position of that element. E.g. calling my_2d_array(4,3) would return:
[[00, 01, 02],
[10, 11, 12],
[20, 21, 22],
[30, 31, 32]]
The main function should execute my_2d_array and be able to potentially perform calculations with the result or modify it.
This is my attempt (with errors):
int my_2d_array(int N, int M) {
int A[N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::string element = std::to_string(i) + std::to_string(j);
A[i][j] = element;
}
}
return A;
}
void main() {
int N, M;
N = 4;
M = 3;
int A[N][M] = my_2d_array(N, M);
// Print the array A
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::cout << A[i][j] << " ";
}
std::cout << "\n";
}
}
One (1) dimensional attempt of #JustLearning's suggestion:
int my_array(int N) {
std::array<int, N> A;
for (int i = 0; i < N; i++) {
A[i] = i;
}
return A;
}
int main() {
int N = 4;
int A[N] = my_array(N);
// Print the array A
for (int i = 0; i < N; i++) {
std::cout << A[i] << " ";
}
}
You can use a 2d vector like this
vector<vector int> A;
It works the same way as a 2d array
Welcome to C++! Your function my_2d_array has a couple of issues:
the return type is int, however you are attempting to return an array of ints.
the identifier of an array in C++ is actually a pointer to the first element of that array. Therefore, when you return A, you must be aware of how it should be passed to a new variable in the main part of the code. In particular, your code is passing a reference to a temporary variable A, which is not permitted or safe.
In addition, in C++, unless you know what you're doing, main should always return an int:
int main() { ... }
What is not clear from your question is whether you are attempting to implement your own "array" class, or simply want to use arrays already established in the standard. For the latter, std::array is a good place to start. The advantage is that you can return std::arrays from functions like you return ints or doubles.
std::arrays are good if you plan to work with arrays of fixed size, as the size becomes part of the type: std::array<int, 3> my_array;. Then you can fill it in manually or with member functions of the class (see dox linked above).
If for some reason you prefer to work with arrays of dynamical size (sizes that will change during running your program), std::vector is the way to go.
Finally, if you are actually learning C++ by attempting to implement a container MyArray, you should specify that in your question and be a bit more specific in what help you need.
Here's a working example in 1d:
#include <iostream>
#include <array>
template <int N>
std::array<int, N> my_array() {
std::array<int, N> A;
for (int i = 0; i < N; i++) {
A[i] = i;
}
return A;
}
int main() {
const int N = 4;
std::array<int, N> arr = my_array<N>();
// Print the array A
for (int i = 0; i < N; i++) {
std::cout << arr[i] << " ";
}
}
Since the size of a std::array is included it its type, you need to create a function template, which is basically a function that works for different types. (In C++, std::array<int, 3> and std::array<int, 4> are considered different types.)
In order to use this in main, the index is promoted to a const int, as plain ints can vary during run time, and therefore are not suitable for defining types. (In C++ jargon, look up constant expressions).
Finally, note that both the return type and the type of the variable that receives the value returned by the function must be std::array, not int as you tried in your 1d code.
Following your comment, I can see why you are confused in your attempts to use a matrix in code.
There are many types of containers in C++. Many of them you can find in the standard library (std::vector, std::list, std::set, ...), others you can create yourself or use other libraries. Plain arrays (like int a[5]) are a somewhat unique case because they come from C and are part of the language itself.
A plain array lives on the stack (not very important but you might want to read up on stack vs heap allocations), and refers to a contiguous region of memory.
If you declare some array a like int a[5], you get a region of 5 integers one after the other, and you can point to the first one by just writing a. You can access each of them using a[i] or, equivalently, *(a+i).
If you declare a like int a[5][3], you now get a region of 15 integers, but you can access them slightly differently, like a[i][j], which is equivalent to *(a+i*3+j).
The important thing to you here is that the sizes (5 and 3) must be compile-time constants, and you cannot change them at runtime.
The same is true for std::array: you could declare a like std::array<std::array<int, 3, 5> a and get a similar region of 15 integers, that you can access the same way, but with some convenience (for example you can return that type, whereas you cannot return a plain array type, only a pointer, losing the size information in the process).
My advice is not to think of these arrays as having dimensionality, but as simple containers that give you some memory to work with however you choose. You can very well declare a like std::array<int, 15> a and access elements in a 2D way by indexing like this: a[i*3+j]. Memory-wise, it's the same.
Now, if you want the ability to set the sizes at runtime, you can use std::vector in a similar way. Either you declare a like std::vector<std::vector<int>> a(5, std::vector<int>(3)) and deal with the nested vectors (that initialization creates 5 std::vector<int> of size 3 each), or you declare a as a single vector like std::vector<int> a(15) and index it like a[i*3+j]. You can even make your own class that wraps a vector and helps with the indexing.
Either way, it's rare in C++ to need a plain array, and you should generally use some kind of container, with std::vector being a good choice for a lot of things.
Here is an example of how your code would look like using vectors:
#include <vector>
#include <string>
#include <iostream>
std::vector<std::string> my_2d_array(int N, int M) {
std::vector<std::string> A(N*M);
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::string element = std::to_string(i) + std::to_string(j);
A[i*M+j] = element;
}
}
return A;
}
int main() {
int N, M;
N = 4;
M = 3;
std::vector<std::string> A = my_2d_array(N, M);
// Print the array A
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::cout << A[i*M+j] << " ";
}
std::cout << "\n";
}
}
And here is a very crude example of a Matrix class used to wrap the vectors:
#include <vector>
#include <string>
#include <iostream>
template<typename T>
class Matrix {
public:
Matrix(int rowCount, int columnCount) : v(rowCount*columnCount), columnCount(columnCount) {}
T& operator()(int row, int column) {
return v[row*columnCount + column];
}
private:
std::vector<T> v;
int columnCount;
};
Matrix<std::string> my_2d_array(int N, int M) {
Matrix<std::string> A(N, M);
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::string element = std::to_string(i) + std::to_string(j);
A(i, j) = element;
}
}
return A;
}
int main() {
int N, M;
N = 4;
M = 3;
Matrix<std::string> A = my_2d_array(N, M);
// Print the array A
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::cout << A(i, j) << " ";
}
std::cout << "\n";
}
}
I'm trying to implement a function that returns an array, I came to this solution, but I don't know if it is a good practice, that's how I did it:
#include <iostream>
using namespace std;
int* returnNewArray(int n) {
int* arr = new int[n];
for (int i=0;i<n;i++)
arr[i] = i;
return arr;
}
int main() {
int n = 5;
int* arr = returnNewArray(n);
for (int i=0;i<n;i++)
cout << arr[i] << "\t";
delete[] arr;
arr = NULL;
cout << endl;
}
I wonder if it is necessary to deallocate the memory that I allocated in the function to create the dynamic array (arr).
I don't know if it is a good practice
It's not. Nowadays, cases where using new/new[] and delete/delete[] are necessary are very few.
I wonder if it is necessary to deallocate the memory that I allocated in the function
It is necessary if you want to avoid memory leaks and since you used a raw owning pointer, you need to do it manually, just like you do in your code. Your code is cleaning up correctly.
Good practice would however be to use a std::vector<int> or at least use a smart pointer like std::unique_ptr<int[]> instead since these will clean up memory automatically when they go out of scope.
vector<int> version:
#include <numeric> // std::iota
#include <vector> // std::vector
std::vector<int> returnNewArray(size_t n) {
std::vector<int> arr(n);
std::iota(arr.begin(), arr.end(), 0); // [0, n)
return arr;
}
unique_ptr<int[]> version:
#include <memory> // std::unique_ptr / std::make_unique_for_overwrite
#include <numeric> // std::iota
std::unique_ptr<int[]> returnNewArray(size_t n) {
auto arr = std::make_unique_for_overwrite<int[]>(n);
std::iota(arr.get(), arr.get() + n, 0); // [0, n)
return arr;
}
Both versions will let you iterate over the result just like you do in your code - and you don't have to delete[] anything when you're done:
auto arr = returnNewArray(n);
for(int i = 0; i < n; ++i)
std::cout << arr[i] << '\t'; // 0 1 2 3 4
But the std::vector<int> has the benefit of knowing its own size and can be used in range based for-loops, which also helps to not accidentally access the array out-of-bounds:
for (int value : arr) // range based for-loop
std::cout << value << '\t'; // 0 1 2 3 4
The below is the basic code. I want to make the array globally so that i don't have to call it for every function.Now how do I initialize the 2d array with -1. I tried to use memset(arr,-1,sizeof(arr)) just below line 3, but it didn't worked out, so, can anyone tell me what am I doing wrong??
#include <bits/stdc++.h>
using namespace std;
int arr[10][10];
int func(){
//this function will be using the global arr
// if(arr[x][y]!=-1)
//do something
}
int main(){
//the code
}
I do not know the good way to initialize a built-in array in place without code repetition. I do, however, know a way to initialize std::array:
#include <array>
#include <utility>
#include <cstddef>
template<size_t... Ix>
auto constexpr make1array(int v, std::index_sequence<Ix...>) {
auto populate = [](int v, size_t) { return v; };
std::array<int, 10> a = { populate(v, Ix)... };
return a;
}
template<size_t... Ix1, size_t... Ix2>
auto constexpr make2array(int v, std::index_sequence<Ix1...> seq, std::index_sequence<Ix2...>) {
auto populate = [](auto v, size_t) { return v; };
std::array<std::array<int, 10>, 10> a = { populate(make1array(v, seq), Ix2)... };
return a;
}
std::array<std::array<int, 10>, 10> arr = make2array(-1, std::make_index_sequence<10>{}, std::make_index_sequence<10>{});
This code produces an array pre-populated with -1 as the value at compile time.
The function memset won't work because memset uses bytes and many integers occupy more than one byte.
IMHO, your best source is to use std::fill.
Example:
std::fill(&arr[0][0], &arr[9][9] + 1, -1);
Otherwise, you can always fall back on the nested loop:
for (int r = 0; r < MAX_ROWS; ++r)
{
for (int c = 0; c < MAX_COLUMNS; ++c)
{
arr[r][c] = -1;
}
}
Your best bet is to let the compiler optimize the nested loops.
There may be some micro-optimizations that you could employ, but the compiler probably already has them in its tool chest.
There is no direct way to initialize raw array by values that aren't result of default initialization. One of the reasons is that array cannot be returned from function and cannot be assigned directly from anything that is not a {}-list.
Simplest way (since C++14) is to make it part of class-type with constexpr constructor. In C++111 constructor with non-empty body cannot be constexpr.
#include <iostream>
struct MinusOneArray {
static constexpr int NX = 10;
static constexpr int NY = 10;
int arr[NX][NY];
constexpr MinusOneArray() : arr() {
for(int i = 0; i < NX; ++i)
for(int j = 0; j < NY; ++j)
arr[i][j] = -1;
}
};
int main()
{
MinusOneArray a;
auto &arr = a.arr;
for(auto &line: arr) {
for(auto val: line)
std::cout << val << ",";
std::cout << std::endl;
}
}
Alternative is to use standard structure std::array and initialize it with constexpr function, how SergeyA offered.
Here I'm trying to user c++11 range base loop for tow integer arrays. one declared using new keyword and other not.
#include <iostream>
#include <stdlib.h>
#define ARRAY_LENGTH 100
int main()
{
int* heap_array = new int[ARRAY_LENGTH];
int stack_aray[ARRAY_LENGTH];
for(int i=0; i < ARRAY_LENGTH; i++)
{
int val = (rand() % ARRAY_LENGTH) + 1;
heap_array[i] = val;
stack_array[i] = val;
}
for(int& i : stack_array){ std::cout << i << std::endl;}
for(int& i : *heap_array){ std::cout << i << std::endl;} // compile error
delete[] heap_array;
return 0;
}
Why range base loop doesn't work for the array declared with new keyword? my view is it doesn't matter heap or stack both are heap_array & stack_array are pointers to the first element.
Your heap_array isn't really an array but a raw pointer to an int. A raw pointer does not know anything about the number of elements allocated.
I am trying to copy a vector into an array however I don't know how to declare the array from the size of the vector.
Code:
int main() {
vector<int> ivec = {1, 2, 3, 4, 5};
constexpr size_t size = ivec.size();
int arr[size];
for(size_t i = 0; i < ivec.size(); ++i)
arr[i] = ivec[i];
for(size_t i : arr)
cout << i << endl;
return 0;
}
However, I think this won't compile because ivec.size() can't be a constant expression (though I'm not sure if this is the case). In which case how could I do this without having to manually enter the number of elements?
As of right now std::vector size() is not a constexpr, so you cannot use it in constexpressions. As a result, you can try using the new keyword for dynamically sized arrays, but that would be pointless, as you're already using a vector.
vector<int> vi = {1, 2, 3, 4, 5};
int* arr = new int[vi.size()];
std::copy(vi.begin(), vi.end(), arr);
for (unsigned int i = 0; i < vi.size(); i++)
std::cout << arr[i] << " ";
delete[] arr;
Note:: You can use std::begin() with the second example because arr[] is an array but not with the first example because arr* is a pointer. However, std::copy() accepts both, so it should be fine.
initializer_lists can be used in constexpressions:
constexpr initializer_list<int> il = {1, 2, 3, 4, 5};
int arr[il.size()];
std::copy(il.begin(), il.end(), std::begin(arr));
for (unsigned int i = 0; i < il.size(); i++)
std::cout << arr[i] << " ";
In general, it is not possible to copy a vector into array, because, a usual array is constexpr, while vector size is not, it is of dynamic size. There are also dynamic arrays supported by some compilers, but then again, there size is never constexpr.
I guess, you need just to use vector.
I don't know your motivation, but...
int main() {
vector<int> ivec = {1, 2, 3, 4, 5};
constexpr size_t size = ivec.size();
int* arr = (int*)malloc( sizeof( int * size ) );
for(size_t i = 0; i < ivec.size(); ++i)
arr[i] = ivec[i];
for(size_t i : arr)
cout << i << endl;
free( arr );
return 0;
}
You need to allocate memory, because as you have said vector size is not a constant:
int main() {
vector<int> ivec = { 1, 2, 3, 4, 5 };
size_t size = ivec.size();
int *arr = new int[size]; // allocate memory
for (size_t i = 0; i < ivec.size(); ++i)
arr[i] = ivec[i];
for (size_t i = 0; i < size; ++i)
cout << i << endl;
delete [] arr; // release memory
return 0;
}
It seems you want to get hold of the number of the elements in an initializer list yielding a constexpr. The only way I'm aware of doing this is to use
#include <cstddef>
template <typename T, std::size_t N>
constexpr std::size_t size(T(&)[N]) {
return N;
}
int main() {
int vec[] = { 1, 2, 3, 4, 5 };
constexpr std::size_t s = size(vec);
int array[s];
std::copy(std::begin(vec), std::end(vec), array);
}
If you really need to use a std::vector<T> as source, you'll need to allocate memory, probably using std::vector<T> in the first place! If you want to allocate the memory yourself you'd use it something like this:
std::vector<int> vec = { 1, 2, 3, 4, 5 };
std::unique_ptr<int[]> array(new int[vec.size()]);
std::copy(vec.begin(), vec.end(), array.get());
The use of std::unique_ptr<int[]> makes sure that the allocated memory is released automatically.
A constexpr is a Constant Expression which is an expression that is evaluated at compile-time. That it is known at compile-time is a fundamental trait of a constexpr.
Given this, you can see how it makes no sense to try to construct a non-dynamically-allocated C-style array at run time when the number of elements will only be known at run-time. The two ideas are orthogonal.
From a technical standpoint, you cannot initialize a constexpr from a non-constant-expression. vector::size() is non-constexpr, so as you suspect, it is not only not compilable, but it is also not logical from a design standpoint to try to construct a constexpr from it:
constexpr size_t size = ivec.size(); // NO GOOD!
All this being said, it's very rare to need to construct a C-style array from vector. You're already doing the Right Thing by using vector in the first place. Don't mess it all up now by copying it to a crappy array.
A vector is guaranteed to have contigious storage. What this means is you can use it just like a C-style array in most cases. All you need to do is pass the address (or reference) to the first element in the vector to whatever is expecting a C-style array and it will work just fine.
void AincentApiFunction (int* array, size_t sizeofArray);
int main()
{
std::vector <int> v;
// ...
AincentApiFunction (&v[0], v.size());
}
I'd avoid
constexpr size_t size = ivec.size();
int arr[size];
and do it like this
size_t size = ivec.size();
int* arr = new int[size];
and then you handle it like the constantly allocated array. Read more about dynamically allocated arrays.
and don't forget to
delete[] array;
In C++11 arrays may declared as runtime bound on the stack:
(Note: this is only per the latest available draft: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf and will likely not be standard, but g++ with -std=c++11 will allow it
Note that is is not constexpression:
8.3.4 Arrays [dcl.array]
D1 [ expressionopt] attribute-specifier-seqopt
Example from the standard:
void f(unsigned int n) {
int a[n]; // type of a is “array of runtime bound of int”
}
So all you need to do is remove constexpr:
int main() {
vector<int> ivec = {1, 2, 3, 4, 5};
size_t size = ivec.size(); // this is fine
int arr[size];
for(size_t i = 0; i < ivec.size(); ++i)
arr[i] = ivec[i];
for(size_t i : arr)
cout << i << endl;
return 0;
}
Your compiler may or may not allow this, so depends on how strictly standard you need to be