So how would I create an array which would contain pointers to other arrays, so that I can still access the arrays that the overall array points to? I tried this:
#include <iostream>
using namespace std;
int main (void)
{
bool (*arrays)[3], *arr1, *arr2, *arr3, *tempArr;
arr1 = new bool[2];
arr2 = new bool[2];
arr3 = new bool[2];
arr1[0] = arr2[0] = arr3[0] = 0;
arr1[1] = arr2[1] = arr3[1] = 1;
arrays[0] = arr1;
arrays[1] = arr2;
arrays[2] = arr3;
int n = 0;
while (n <= 2) {
tempArr = arrays[n];
cout << tempArr[0] << tempArr[1] << "\n";
}
}
Also, how would I make the overall array ("arrays") a pointer so that I can add new arrays to it? I made a preliminary function, but it doesn't work (note "paths" is the overall array):
void addPath (void)
{
int n = getArrayLength(paths), i = 0;
bool (*newPaths)[n + 1];
while (i < n) {
newPaths[i] = paths[i];
++i;
}
delete [] paths;
newPaths[n] = tempPath;
paths = newPaths;
}
Hopefully this isn't to confusing or absurd, and thank you for your help.
It appears that you're looking for std::vector:
#include <vector>
std::vector<std::vector<bool> > paths;
Note, however, that std::vector<bool> isn't a normal "container", and doesn't support all the operations of a normal container like vector<any_type_other_than_bool> would.
You could use malloc. Of course, that's kind of C code, not C++:
#include <cstring>
#include <cstdlib>
size_t ptrArraySize = 3;
bool** arrays = (bool**) malloc(ptrArraySize * sizeof(bool*));
Or, you could do as Jerry Coffin suggested. However, this doesn't give you a vector with pointers to vectors. It gives you a vector of vectors (so stack allocated, not on the heap). To get a vector of pointers to vectors, you could do something like:
#include <vector>
std::vector<std::vector<bool> * > ptrVector;
std::vector<bool> * vectorA = new std::vector<bool>();
vectorA->push_back(true);
ptrVector.push_back(vectorA);
Another possibility is using one of boost::scoped_array or boost::shared_array, depending on your needs.
bool (*arrays)[3] declares arrays to be a pointer to an array of 3 bools -- you want an array of 3 pointers to bools, or bool *arrays[3]. To make a pointer to that dynamically, you want just bool **arrays = new bool*[3];
Related
How to create a dynamic array of integers in C++ using the new keyword?
int main()
{
int size;
std::cin >> size;
int *array = new int[size];
delete [] array;
return 0;
}
Don't forget to delete every array you allocate with new.
Since C++11, there's a safe alternative to new[] and delete[] which is zero-overhead unlike std::vector:
std::unique_ptr<int[]> array(new int[size]);
In C++14:
auto array = std::make_unique<int[]>(size);
Both of the above rely on the same header file, #include <memory>
You might want to consider using the Standard Template Library . It's simple and easy to use, plus you don't have to worry about memory allocations.
http://www.cplusplus.com/reference/stl/vector/vector/
int size = 5; // declare the size of the vector
vector<int> myvector(size, 0); // create a vector to hold "size" int's
// all initialized to zero
myvector[0] = 1234; // assign values like a c++ array
int* array = new int[size];
As soon as question is about dynamic array you may want not just to create array with variable size, but also to change it's size during runtime. Here is an example with memcpy, you can use memcpy_s or std::copy as well. Depending on compiler, <memory.h> or <string.h> may be required. When using this functions you allocate new memory region, copy values of original memory regions to it and then release them.
// create desired array dynamically
size_t length;
length = 100; //for example
int *array = new int[length];
// now let's change is's size - e.g. add 50 new elements
size_t added = 50;
int *added_array = new int[added];
/*
somehow set values to given arrays
*/
// add elements to array
int* temp = new int[length + added];
memcpy(temp, array, length * sizeof(int));
memcpy(temp + length, added_array, added * sizeof(int));
delete[] array;
array = temp;
You may use constant 4 instead of sizeof(int).
dynamically allocate some memory using new:
int* array = new int[SIZE];
The answers above are all good for assigning one-dimensional int-arrays. Anyhow, I want to add that it is also possible to do this for multi-dimensional arrays you'd normally define like int[][] matrix = {{1,2}, {3,4}}.
The key is that you store all elements in one array and make use of the fact that the array is a continuous block in memory (see here for a clarification of "block"), meaning that you can "slice" yourself through dimensions. Below you can see an example for a 2d-array.
You can find a discussion regarding this topic here on SO.
/*Defining a 2d-matrix.*/
struct Matrix {
int rows, columns;
int* matrix;
Matrix(int rows, int columns) : rows(rows), columns(columns) {
// This approach uses a single array since "new" cannot create
// multidimensional arrays.
// It also spares the performance cost of an array of arrays.
matrix = new int[columns * rows];
}
~Matrix() {
// Release the memory after destroying the Matrix-object
delete[] matrix;
}
/*Access the element at position [r]ow and [c]olumn.*/
int getElement(int r, int c) {
// matrix[c][r] is rewritten as matrix[column + columns * rows]
// -> matrix <=> Single memory block
return matrix[c + columns * r];
}
/*Set the element at position [r]ow and [c]olumn with given [val]ue.*/
void setElement(int r, int c, int val) {
matrix[c + columns * r] = val;
}
};
An example to populate such a Matrix-object would be:
/*Initialize the matrix with the continuous numbers 0..N*/
void Matrix::initDummyMatrix(){
int counter = 0;
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < columns; ++col) {
setElement(row, col, counter++);
}
}
}
#include <stdio.h>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
float arr[2095879];
long k,i;
char ch[100];
k=0;
do{
cin>>ch;
arr[k]=atof(ch);
k++;
}while(ch[0]=='0');
cout<<"Array output"<<endl;
for(i=0;i<k;i++){
cout<<arr[i]<<endl;
}
return 0;
}
The above code works, the maximum float or int array size that could be defined was with size 2095879, and exit condition would be non zero beginning input number
In order not to have to remember to delete, we are using unique_ptr to manage the memory.
We were under the impression that we can write and read in the memory, just that deletion is up to the smart pointer. However, the following code crashes on i=7220 with a segfault.
What is wrong?
#include <memory>
using namespace std;
int main() {
const uint32_t n = 40000000;
uint64_t*p = new uint64_t[n]; // this works, but we have to delete the memory or leak
for (int i = 0; i < n; i++)
p[i] = i;
unique_ptr<uint64_t> mem = make_unique<uint64_t>(n);
uint64_t* p1 = mem.get();
for (int i = 0; i < n; i++) // this crashes at i=7220
p1[i] = i;
return 0;
}
unique_ptr<uint64_t> mem = make_unique<uint64_t>(n);
This allocates one uint64_t dynamically with the value n.
You want:
unique_ptr<uint64_t[]> mem = make_unique<uint64_t[]>(n);
This specialization allocates an array of uint64_t with n elements, and has an operator[] overload which makes the below possible:
for (int i = 0; i < n; i++)
mem[i] = i;
So, there's no need to do uint64_t* p1 = mem.get();
unique_ptr<uint64_t> is a pointer to a single uint64_t value. In order to make it store an array you need to use array of unknown bound syntax:
unique_ptr<uint64_t[]> mem = make_unique<uint64_t[]>(n);
or just
auto mem{make_unique<uint64_t[]>(n)};
Note that this variant overloads operator [] so there is no need to create an intermediate raw pointer uint64_t* p1 = mem.get();
Aside from the fix other answers mentioned, you likely don't want to use make_unique here. make_unique will zero-out every single element (40 million ints!) and you immediately overwrite them. Your options are to use make_unique_for_overwrite which requires C++20, or to use new:
#include <cstdint> // for uint64_t
#include <memory> // for unique_ptr, unique_ptr<>::pointer
#include <numeric> // for iota
int main() {
auto const n = 40'000'000;
auto const p = std::unique_ptr<std::uint64_t[]>{new std::uint64_t[n]};
std::iota(p.get(), p.get() + n, 0);
}
On a project I'm working on, I need some dynamic allocation due to the size of the used data not been known in advance. std::vector seems perfect for this use case. However, due to the software environnement, I can not use "modern" C++ in the headers. I would like to convert this vectors array to be used in fuction with compliant headers.
Quick example:
void func(int tab[][]/*Vector can not be used here*/){/*Do things*/}
int main(){
std::vector<int> vecTab[6/*Fixed, prior known, dimension*/];
//Adding a random number of values in each vector (equal number in each one)
//Transformation of vecTab
func(vecTabMod);
return 1;
}
There is a lot of similar questions on this site, none of them really adressing bi-dimensionnal arrays.
Bonus point: no reallocation, access through pointers
You'll need to copy the data pointers into a separate array so that the type and layout matches what the funciton expects. This can be done without heap allocation since the size of this array is fixed.
int* vecTabMod[6];
std::transform(std::begin(vecTab), std::end(vecTab), std::begin(vecTabMod),
[](auto& v) { return v.data(); });
func(vecTabMod);
std::vector is worst choice for this soultion!
Using dynamic arrays is better.
Anyway you can use this code:
#include <vector>
#include <iostream>
int func(uint32_t firstDimensionSize, uint32_t* secoundDimensionSizes, int** tab){
int sum = 0;
for(uint32_t i = 0; i < firstDimensionSize; i++){
for(uint32_t j = 0; j < secoundDimensionSizes[i]; j++){
sum += tab[i][j];
}
}
return sum;
}
int main(){
std::vector<int> vecTab[6];
vecTab[0].push_back(2);
vecTab[0].push_back(5);
vecTab[3].push_back(43);
// Calculate count of elements in non dynamically arrays
uint32_t firstDimensionSize = (sizeof(vecTab) / sizeof((vecTab)[0]));
uint32_t* secoundDimensionSizes = new uint32_t[firstDimensionSize];
int**tab = new int*[firstDimensionSize];
for(uint32_t i = 0; i < firstDimensionSize; i++){
secoundDimensionSizes[i] = vecTab[i].size();
tab[i] = &(vecTab[i][0]);
}
std::cout << func(firstDimensionSize, secoundDimensionSizes, tab) << std::endl;
delete[] secoundDimensionSizes;
delete[] tab;
system("pause");
}
How to create a dynamic array of integers in C++ using the new keyword?
int main()
{
int size;
std::cin >> size;
int *array = new int[size];
delete [] array;
return 0;
}
Don't forget to delete every array you allocate with new.
Since C++11, there's a safe alternative to new[] and delete[] which is zero-overhead unlike std::vector:
std::unique_ptr<int[]> array(new int[size]);
In C++14:
auto array = std::make_unique<int[]>(size);
Both of the above rely on the same header file, #include <memory>
You might want to consider using the Standard Template Library . It's simple and easy to use, plus you don't have to worry about memory allocations.
http://www.cplusplus.com/reference/stl/vector/vector/
int size = 5; // declare the size of the vector
vector<int> myvector(size, 0); // create a vector to hold "size" int's
// all initialized to zero
myvector[0] = 1234; // assign values like a c++ array
int* array = new int[size];
As soon as question is about dynamic array you may want not just to create array with variable size, but also to change it's size during runtime. Here is an example with memcpy, you can use memcpy_s or std::copy as well. Depending on compiler, <memory.h> or <string.h> may be required. When using this functions you allocate new memory region, copy values of original memory regions to it and then release them.
// create desired array dynamically
size_t length;
length = 100; //for example
int *array = new int[length];
// now let's change is's size - e.g. add 50 new elements
size_t added = 50;
int *added_array = new int[added];
/*
somehow set values to given arrays
*/
// add elements to array
int* temp = new int[length + added];
memcpy(temp, array, length * sizeof(int));
memcpy(temp + length, added_array, added * sizeof(int));
delete[] array;
array = temp;
You may use constant 4 instead of sizeof(int).
dynamically allocate some memory using new:
int* array = new int[SIZE];
The answers above are all good for assigning one-dimensional int-arrays. Anyhow, I want to add that it is also possible to do this for multi-dimensional arrays you'd normally define like int[][] matrix = {{1,2}, {3,4}}.
The key is that you store all elements in one array and make use of the fact that the array is a continuous block in memory (see here for a clarification of "block"), meaning that you can "slice" yourself through dimensions. Below you can see an example for a 2d-array.
You can find a discussion regarding this topic here on SO.
/*Defining a 2d-matrix.*/
struct Matrix {
int rows, columns;
int* matrix;
Matrix(int rows, int columns) : rows(rows), columns(columns) {
// This approach uses a single array since "new" cannot create
// multidimensional arrays.
// It also spares the performance cost of an array of arrays.
matrix = new int[columns * rows];
}
~Matrix() {
// Release the memory after destroying the Matrix-object
delete[] matrix;
}
/*Access the element at position [r]ow and [c]olumn.*/
int getElement(int r, int c) {
// matrix[c][r] is rewritten as matrix[column + columns * rows]
// -> matrix <=> Single memory block
return matrix[c + columns * r];
}
/*Set the element at position [r]ow and [c]olumn with given [val]ue.*/
void setElement(int r, int c, int val) {
matrix[c + columns * r] = val;
}
};
An example to populate such a Matrix-object would be:
/*Initialize the matrix with the continuous numbers 0..N*/
void Matrix::initDummyMatrix(){
int counter = 0;
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < columns; ++col) {
setElement(row, col, counter++);
}
}
}
#include <stdio.h>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
float arr[2095879];
long k,i;
char ch[100];
k=0;
do{
cin>>ch;
arr[k]=atof(ch);
k++;
}while(ch[0]=='0');
cout<<"Array output"<<endl;
for(i=0;i<k;i++){
cout<<arr[i]<<endl;
}
return 0;
}
The above code works, the maximum float or int array size that could be defined was with size 2095879, and exit condition would be non zero beginning input number
I have a dynamically created array of integers. Now I have to remove all elements which have index %3 == 0. (for example, 3, 6, 9, ...). So, what is the best way to decrease array size? With malloc I can use realloc for the same part of memory, but what about new operator? What to do this way. Just slide all elements left, make zero to all another elements?
#include <algorithm>
#include <iostream>
#include <vector>
bool IsDividedByThree (int i) { return ((i%3)==0); }
int RandomNumber () { return (rand()%100); }
int main()
{
std::vector<int> myInts(50);
std::generate(myInts.begin(), myInts.end(), RandomNumber);
std::copy(myInts.begin(), myInts.end(), std::ostream_iterator<int>(std::cout, " "));
myInts.erase(std::remove_if(myInts.begin(), myInts.end(), IsDividedByThree), myInts.end());
std::copy(myInts.begin(), myInts.end(), std::ostream_iterator<int>(std::cout, " "));
}
Isn't so nice that STL takes care everything for you?
Hm didn't see comment, in which one is forced not to use STL.
The C version:
int *temp = new int[NEW_SIZE];
memcpy( temp , old_array, size_of_old_array * sizeof(int) );
delete[] old_array;
old_array = temp;
create the array dynamically
create a new array with the new size
copy the elements from the first to the second array
delete the first array
redirect the pointer to the first array to the second
All these answer So, what is the best way to decrease array size? - I assumed you already knew how to solve the rest of your problem.
I'd simply allocate a new smaller array and then copy elements to it. Something like this (this includes the element at 0 index):
int* array = new int [original_size];
// fill array
size_t new_size = original_size - original_size / 3 - 1; // i think i got this right, untested
int* new_array = new int [new_size];
for (int i = 0, int j = 0; i < original_size; i++)
{
if (i % 3 == 0)
{
new_array[j] = array[i];
j++
}
}
delete [] array;
array = new_array;
new_array = nullptr;
You can of course work in place and shift elements to the left. But you can't delete a part of array that was allocated via new[].
Since this is an exercise, and you can't use STL, why don't you try to implement a simple vector class yourself?
You can use placement new operator in C++. (#include <new> is required). For example
#include <new>
int main(int argc, char **argv) {
double *b = new double[10];
new(b) double[8];
delete [] b;
}
Simply setting data elements to 0 wont free them. And when you allocate new memory for the resized array, you need to copy all of the elements from previous memory.
I would suggest you to implement it as a linked list.