I want to initialize an array and then initialize a pointer to that array.
int *pointer;
pointer = new int[4] = {3,4,2,6};
delete[] pointer;
pointer = new int[4] = {2,7,3,8};
delete[] pointer;
How can I do this?
Why not use
int array[4] = {3, 4, 2, 6};
Is there a reason you want to allocate memory for the array from heap?
Suggestion after comment:
int arrays[32][4] = {{3, 4, 2, 6}, {3, 4, 1, 2}, ...}
int *pointers[4];
pointers[0] = arrays[0];
pointers[1] = arrays[12];
pointers[2] = arrays[25];
pointers[3] = arrays[13];
...
pointers[0] = arrays[13];
pointers[1] = arrays[11];
pointers[2] = arrays[21];
pointers[3] = arrays[6];
int *pointer = new int[4]{3,4,2,6};
EDIT: As pointed out in the comments, this is C++0x syntax. To do this in earlier versions, write a function that takes a stack array + size, allocates a new array on the heap, loops through the stack array populating the heap array, and then returning a pointer to the heap array.
int* foo( const int size, int *array )
{
int *newArray = new int[size];
for( int index = 0; index < size; ++index )
{
newArray[index] = array[index];
}
return newArray;
}
The call would look like this:
int a[] = { 1, 2, 3, 4 };
int *ptr = foo( 4, a );
It takes two lines, but it at least is easier than initializing line by line.
//initialize the array
int array[] = {3,4,2,6};
// initialize a pointer to that array
int *pointer = array;
As others have pointed out, you can initialize non heap arrays, e.g.:
static const int ar1[4] = { ... };
static const int ar2[4] = { ... };
Then initialize your dynamically allocated array from the static data:
void func()
{
int *pointer = new int[4];
...
memcpy(pointer, ar1, sizeof(ar1));
...
memcpy(pointer, ar2, sizeof(ar2));
...
You can do something like this with a standard container and boost::assign.
std::vector vect = list_of(3)(4)(2)(6);
...
vect = list_of(2)(7)(3)(8);
Related
I am a beginner in c++ and I am wondering how do you delete and append values to arrays.
What I mean is like this:
int arr[] = {1, 2, 3, 4}
I want to turn it into:
int arr[] = {1, 2, 3}
by deleting the last value of the array.
Also,
I would like to know how to append the a value to the end of an array. Like this:
int arr[] = {1, 2, 3, 4}
Into this:
int arr[] = {1, 2, 3, 4, 5}
Can anyone help me.
Thanks.
You can't, without new/delete, but std::vector is better. Here's an example of both.
#include <iostream>
#include <vector>
int main() {
// With new/delete:
int *array = new int[3];
array[0] = 1;
array[1] = 2;
array[2] = 3;
// `array` processing...
int *array2 = new int[4];
for (int i = 0; i < 3; i++) {
// copy old data into new array (array2)
array2[i] = array[i];
}
array2[3] = 4;
delete []array;
// `array2` processing...
delete []array2;
// With STL vector:
std::vector<int> array3;
array3.resize(3);
array3[0] = 1;
array3[1] = 2;
array3[2] = 3;
// `array3` processing...
// Add any number of elements
array3.push_back(4);
// resized `array3` processing...
return 0;
}
i would like to ask, why this code doesnt work...
int* funkce(){
int array[] = {1,2,3,4,5};
return(array);
}
int main(){
int* pp = funkce();
int* ppk = pp+5;
for (int *i = pp; i!=ppk; i++){
cout << (*i) << endl;
}
system("PAUSE");
return(0);
}
This code display:
1
16989655
4651388
- // -
253936048
So the poniter is out of array...
But how is possible, that this code with array in Main is ok?
int main(){
int a[] = {1,2,3,4,5};
int* pp = a;
int* ppk = pp+5;
for (int *i = pp; i!=ppk; i++){
cout << (*i) << endl;
}
system("PAUSE");
return(0);
}
this code displayed:
1
2
3
4
5
Could you explain to me, why the first one doesnt work?
Thank you!
You're returning a pointer to a temporary which goes out of scope when the function ends. If you want to have a function return an array, you need to do one of:
std::array<int, 5> func() {
// stack-allocated
std::array<int, 5> a = {1, 2, 3, 4, 5};
return a;
}
std::vector<int> func() {
// heap-allocated
std::vector<int> a = {1, 2, 3, 4, 5};
return a;
}
int* func() {
// heap-allocated, you have to remember to delete it
int* a = new int[5]{1, 2, 3, 4, 5};
return a;
}
etc. There's more options, but this should give you a good start.
Never return a local a pointer/reference to a variable, that memory is freed/re-used on return.
Using that dangling reference is Undefined Behavior and has unpredictable consequences.
Return an object, a pointer to heap-allocated memory, or save into a caller-supplied buffer.
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
I am trying to declare an array of pointers each of which points to int arrays of different sizes. Any ideas?
From your description it sounds like you are looking for a pointer to a pointer.
int **aofa;
aofa = malloc(sizeof(int*) * NUM_ARRAYS);
for (int i = 0 ; i != NUM_ARRAYS ; i++) {
aofa[i] = malloc(sizeof(int) * getNumItemsInArray(i));
}
for (int i = 0 ; i != NUM_ARRAYS ; i++) {
for (int j = 0 ; j != getNumItemsInArray(i) ; j++) {
aofa[i][j] = i + j;
}
}
NUM_ARRAYS arrays may have different number of elements, as determined by the value returned by the getNumItemsInArray(i) function.
int* ar[2];
int ar1[] = {1,2, 3};
int ar2[] = {5, 6, 7, 8, 9, 10};
ar[0] = ar1;
ar[1] = ar2;
cout << ar[1][2];
C version, should help clarifying the different types of declarations:
#include <stdio.h>
int main()
{
/* let's make the arrays first */
int array_A[3] = {1, 2, 3};
int array_B[3] = {4, 5, 6};
int array_C[3] = {7, 8, 9};
/* now let's declare some pointers to such arrays: */
int (*pA)[3] = &array_A;
int (*pB)[3] = &array_B;
int (*pC)[3] = &array_C; /* notice the difference: */
/* int *pA[3] would be an array of 3 pointers to int because the [] operator*/
/* has a higher precedence than *(pointer) operator. so the statement would */
/* read: array_of_3 elements of type_pointer_to_int */
/* BUT, "int (*pA)[3]" is read: pointer_A (points to) type_array_of_3_ints! */
/* so now we need a different array to hold these pointers: */
/* this is called an_ARRAY_of_3_pointers to_type_array_of_3_ints */
int (*ARRAY[3])[3] = {pA, pB, pC};
/* along with a a double pointer to type_array_of_3_ints: */
int (**PTR)[3] = ARRAY;
/* and check that PTR now points to the first element of ARRAY: */
if (*PTR == pA) printf("PTR points to the first pointer from ARRAY \n");
PTR++;
if (*PTR == pB) printf("PTR points to the second pointer from ARRAY! YAY!\n");
return 0;
}
> $ clang prog.c -Wall -Wextra -std=gnu89 "-ansi" output:
> PTR points to the first pointer from ARRAY
> PTR points to the second pointer from ARRAY! YAY!
Check out the section "Pointers to Arrays of Objects"
http://www.functionx.com/cpp/Lesson24.htm
It might help you.
In C++ you can declare it like shown below.new operator can work like similar to malloc in C.
int** array = new int*[n];
#include <iostream>
using namespace std;
#define arraySize 3
const int arr1[] = {48,49,50};
const int arr2[] = {64,65,66};
const int arr3[] = {67,68,69};
typedef const int (*arrayByte);
arrayByte arrayPointer[arraySize] = {
arr1,arr2,arr3
};
void printArr(const int arr[], int size){
for(uint8_t x=0;x<size;x++){
printf("value%d=%d \n",x,arr[x]);
}
}
int main()
{
printf("Print Array 0\n");
printArr(arrayPointer[0],arraySize);
printf("Print Array 1\n");
printArr(arrayPointer[1],arraySize);
printf("Print Array 2\n");
printArr(arrayPointer[2],arraySize);
return 0;
}
try this code: C++ online
Sample code:
int ar[3];
............
ar[0] = 123;
ar[1] = 456;
ar[2] = 789;
Is there any way to init it shorter? Something like:
int ar[3];
............
ar[] = { 123, 456, 789 };
I don't need solution like:
int ar[] = { 123, 456, 789 };
Definition and initialization must be separate.
What you are asking for cannot be done directly. There are, however different things that you can do there, starting from creation of a local array initialized with the aggregate initialization and then memcpy-ed over your array (valid only for POD types), or using higher level libraries like boost::assign.
// option1
int array[10];
//... code
{
int tmp[10] = { 1, 2, 3, 4, 5 }
memcpy( array, tmp, sizeof array ); // ! beware of both array sizes here!!
} // end of local scope, tmp should go away and compiler can reclaim stack space
I don't have time to check how to do this with boost::assign, as I hardly ever work with raw arrays.
Arrays can be assigned directly:
int a[3] = {1, 2, 3};
Check the C++ Arrays tutorial, too.
int a[] = {1,2,3};
this doesn't work for you?
main()
{
int a[] = {1,3,2};
printf("%d %d %d\n", a[0], a[1], a[2]);
printf("Size: %d\n", (sizeof(a) / sizeof(int)));
}
prints:
1 3 2
Size: 3
What about the C99 array initialization?
int array[] = {
[0] = 5, // array[0] = 5
[3] = 8, // array[3] = 8
[255] = 9, // array[255] = 9
};
#include <iostream>
using namespace std;
int main()
{
int arr[3];
arr[0] = 123, arr[1] = 345, arr[2] = 567;
printf("%d,%d,%d", arr[0], arr[1], arr[2]);
return 0;
}