Using structures and pointer arrays c++ - c++

I am trying to write a pointer array to structs in C++. My main goal is to be able to dynamically add pointers to the array. I am having trouble with the synthax
struct items
{
int member1;
int member2;
};
int N=5;
items **ptr=new item *[N]; // This is a ptr to an array of ptr's. Each ptr
// in this array needs to point to an items struct.
My question is how to write in the struct's objects from this point on. I know I need to create them first but I don't have any idea how to do that.

You're allocating only an array of pointers of item *, you'll need to allocate the memory for each item also, e.g.:
struct item // naming it 'items' might be confusing, and was used inconsistently
// in your code sample
{
int member1;
int member2;
};
int N=5;
item **ptr=new item *[N];
for(int i = 0; i < N; ++i)
{
ptr[i] = new item();
}
Accessing your structure members looks like this:
ptr[2]->member1 = 42; // Sets member1 of the 3rd item element to 42
Note that you'll need to free the allocated memory somewhere as follows:
for(int i = 0; i < N; ++i)
{
delete ptr[i];
}
delete [] ptr;
I general for c++ you'd be better off using a c++ standard container like:
#include <vector>
int N = 5;
std::vector<item> myItems;
myItems.resize(N,item());
myItems[2].member1 = 42; // Sets member1 of the 3rd item element to 42
which would do all the memory management for you internally.
If you're using c++11 and do not need dynamically sized arrays you can even avoid heap allocated memory at all using std::array:
#include <array>
std::array<item,5> myItems; // Size is fixed to 5, you can't use a variable here
myItems[2].member1 = 42; // Sets member1 of the 3rd item element to 42

You can add objects to your array by ptr[i] = new items(). And you can access data in items** ptr by ptr[i]->member1. But I'll strongly recommend using stl containers and smart pointers.

Firstly you have to finish the allocation step.
for(int i=0;i<N;i++)
ptr[i]=new items;
Then you can access the array using e.g.:
ptr[0]->member1=123;

Related

c++ 2d arrays and pointers to pointers- I don't understand this code

I don't understand pointers to pointers or pointers to 2d arrays. I do not understand what the following code does. Can anyone go line by line and explain to me what it is doing? It is really important for me to grasp this concept, but I cannot grasp it.
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
//i understand that we declare a 2d array
int tD[2][2];
//but then i'm confused why there is a pointer to a pointer when there isn't a pointer in the first place
int **tD2;
//and i am confused what the star after int does
tD2 = new int*[2];
//i think i get this
for(int i = 0; i < 2; i++)
tD2[i] = new int[2];
for(int i = 0; i < 2; i++)
delete [] tD2[i];
//lost here
delete [] tD2;
return 0;
}
I will leave comments to explain...
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
//i understand that we declare a 2d array
int tD[2][2];
//but then i'm confused why there is a pointer to a pointer when there isn't a pointer in the first place
int **tD2; // A 1D array is an int*; int** makes an array of int*'s, which are themselves arrays (not necessarily all next to each other).
//and i am confused what the star after int does
tD2 = new int*[2]; // allocates memory for two int*'s.
/*
int* a = new int[2];
int** b = new int*[2];
int*** c = new int**[2];
See the pattern? It's one less * than the type.
*/
//i think i get this
for(int i = 0; i < 2; i++)
tD2[i] = new int[2];
for(int i = 0; i < 2; i++)
delete [] tD2[i]; // deallocates each inner array.
//lost here
delete [] tD2; // deallocate the outer array. (i.e., the array that holds the "inner arrays").
return 0;
}
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
//i understand that we declare a 2d array
int tD[2][2];
//but then i'm confused why there is a pointer to a pointer when there isn't a pointer in the first place
int **tD2;
This defines tD2 as a pointer (the first *) to a pointer ( the second *) to an int. This isn't useful for anything yet because it is just a pointer and hasn't been pointed at anything. Until it points at something it is dangerous.
//and i am confused what the star after int does
tD2 = new int*[2];
This dynamically allocates an array of two pointers (the *) to ints and assigns this array to tD2. tD2 now points at something and is safe to use. However the array of pointers is uninitialized and dangerous.
//i think i get this
for(int i = 0; i < 2; i++)
tD2[i] = new int[2];
This loop dynamically allocates an array of two ints for each of the pointers in the array of pointers to ints allocated above to point at. Now all of the pointers are pointing at something.
for(int i = 0; i < 2; i++)
delete [] tD2[i];
Any memory you dynamically allocate should be returned to from which it came when you are done with it so the memory can be reused or eventually your program will run out of memory. delete [] returns an array and makes sure the appropriate destructors are called. This loop releases the arrays of int.
//lost here
delete [] tD2;
Releases the array of pointers to ints for the same reasons as above.
return 0;
}
Note: This is a horrible way to manage a 2D array. Look at all the work you had to do. Think of how easy it is to forget or be unable to return the memory that was allocated. The programmer has to remember the dimensions or pass them around with tD2 to make sure no one steps out of bounds.
Don't do this. Instead use std::vector.
#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;
int main() {
//i understand that we declare a 2d array
int tD[2][2];
vector<vector<int>> tD2(2, // outer vector contains 2 vectors
vector(2)); // inner vector contains 2 ints
return 0;
}
vector looks after the memory for you. It knows how big all of the dimensions are so it's harder to get lost. It has a method, at, that won't let you go out of bounds. It gets bigger if you need it to get bigger. Take that dynamic array! Best of all, it has libraries full of support functions for searching, sorting and manipulating. You have to be a fool not to use vector.
Don't be a fool.
If your instructor forces you to be a fool, call them a fool under your breath and pretend you are a fool until you've safely passed the class.

How make a dynamic array using void** and void*?

I want to make a dynamic memory array function where in the arguments I can put in any type I want, the count, and the item I want. I've been googling and looking at YT videos, but none of them explain how to do just THAT, and when the item I want is a pointer. For example, I would have this:
struct Entity
{
int health;
int level;
int experience;
char* name;
}
Entity** entitylist = NULL;
int entitycount = 0;
Entity* CreateEntity(/*args for creating an entity*/)
{
Entity* newentity = malloc(sizeof(Entity));
// All of the entity creation stuff and at the end...
AddItemToList(&Entity, &newentity, &entitycount);
}
I know in the function I want to create I would need to pass in references to the specific list, but from that I'm pretty much clueless. I've tried to use malloc and realloc but either crashes the program or does nothing. And would new and delete work for this type of stuff?
And how would removing something like this work? I haven't seen anything on the internet yet about removing an item from a list, only adding them.
Thanks!
Using a double pointer for a data type such as int** with give you a dynamic 2D array, or a dynamic array of pointer objects, depending on your implementation, and a single int* is just a normal dynamic array. To full instantiate and allocate the memory for these, here's how you do it:
1D Dynamic array:
int* arr;
arr = new int[SIZE];
2D Dynamic Array:
int** arr;
arr = new int*[SIZE]; //<- stop here for 1D array of pointer objects
for (int i = 0; i < SIZE; i++)
arr[i] = new int[SIZE2];

c++ how to make pointers point to arrays?

I'm trying to create a pointerlist that points to the previous and next elements. I also want each element to contain an array. How do I define this in the class and/or add the array to the elements of the list
class codes {
public:
int code[];
codes* next;
codes* previous;
};//codes
void addtolist(codes* & entrance, int k[]) {
codes* c;
c = new codes;
c->code[] = k;
c->next = entrance;
if(c->next != NULL){
c->next->previous=c;
}//if
c->previous = NULL;
entrance = c;
}//addtolist
An array is a pointer of sorts already. In C/C++, if I have an array:
int arr[10]
then array access
arr[2];
is just another way of dereferenced pointer access
*(arr + 2);
An array can be passed to a pointer
int getSecond(int* a) {
return a[2];
}
getSecond(arr);
So, if you class is holding an array whose lifetime is managed somewhere else, all you need is a pointer:
class codes {
public:
int* code;
codes* next;
codes* previous;
};//codes
Now if you want your codes class to actually manage the lifetime of the array, or copy the values into the class, you will have to do some additional work.
You create a pointer to some class object like this:
SomeClass *ptr = new SomeClass();
or
SomeClass a;
SomeClass *ptr = &a;
To define array inside your structure, just do inside your structure:
int arr[32];
Just note this is array of fized size. If you want array with dynamic size
declare:
int * arr;
inside your structure, and then at some point make it point to
array objects:
obj.arr = new int[SIZE];
You'll have to call delete[] in the above case when done with array.
That said it might be tricky (see here) to have class which manages dynamic memory internally,
you might prefer array with fixed size.
Do member wise copy of array elements instead of this:
c->code[] = k; // You can't assign like this since code is not a pointer

How can I return a pointer to an array in C++?

Here is my simple code
arrayfunc() should store some numbers in an array, and return the pointer of this array
to main function where the content of the array would be printed
What is the problem with my code?
It only returns the pointer to the first element of the array
Any help will be appreciated.
Thanks in advance.
#include <iostream>
using namespace std;
//The definition of the function should remain the same
int* arrayfunc()
{
int *array[10];
array[0] =new int;
array[1] =new int;
array[2] =new int;
array[3] =new int;
*array[0]=10;
*array[1]=11;
*array[2]=12;
*array[3]=13;
return *array;
}
int main()
{
for(int i=0;i<4;i++)
cout<<*(arrayfunc()+i)<<endl;
return 0;
}
(1) You should allocate your array with new if you want to return it: int* array = new int[10]; [assuming here you want array of ints and not array of int*'s]
(2) to return the pointer to the first element in the array, use return array and not return *array
(3) your array is array of pointers, and not array of ints.
Your array is allocated on stack, so as soon as the function returns, it's freed. So you want to return a pointer to a dead memory.
But you are not doing that, you are just returning the valid (copy of) value of the 0th array item.
So, what you have to do:
The best idea would be to switch to stl containers. You should be using std::vector or something like that.
If you stick to the idea of manual memory management, you have to allocate the array on heap, return it from the function, and perhaps deallocate it in the caller.
Edit:
basically you want the following:
using namespace std;
vector<int> arrayfunc()
{
vector<int> v;
v.push_back(10);
...
return v;
}
...
vector<int> result = arrayfunc();
cout << result[0] << ...
This would be the right C++ way.
(Nitpicking:) You don't need to care about copying the vector, because of the RVO used by all modern C++ compilers.
Allocating an array on heap should be simple, too:
int* array = new int[4];
array[0] = 10;
...
return array;
...
int* array = arrayfunc();
...
delete[] array;
But I would strongly advise to take the former approach (with vector).
This codes seems wrong to me in several levels.
Never return an internal variable of a function. The variable array is only defined in the function, so it should never be returned outside.
Why do you allocate each int by itself with new? I would allocate the entire array at once. If you know the array length and it's constant, consider having it defined statically.
http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx
Just try return array; instead of return *array;

allocation of a pointers to fixed size arrays

I have 2 doubts regarding basics of pointers usage.
With the following code
int (*p_b)[10];
p_b = new int[3][10];
// ..do my stuff
delete [] p_b
p_b is pointing to an array of 3 elements, each having fixed-size length of 10 int.
Q1:
How to declare p_b if I want that each element be a pointer to a fixed array size?
Basically I want the following
p_b[0] = pointer to a fixed-array size of 10
p_b[1] = pointer to a fixed-array size of 10
// ... and so on
I was thinking to int (** p_b)[10] but then I don't know how to use new to allocate it? I would like to avoid falling back to more general int** p_b
Q2:
Is per my original code sample above, how to call new so that p_b points to a unique fixed-size array of 10 int other than calling p_b = new int[1][10] ? To free memory I have to call delete[] while I cannot find an expression where I can call only simply delete.
p_b is pointing to an array of 3 elements, each having fixed-size length of 10 int.
How to declare p_b if I want that each element be a pointer to a fixed array size?
Does your first sentence not completely cover that question?
Is per my original code sample above, how to call new so that p_b points to a unique fixed-size array of 10 int other than calling p_b = new int[1][10]? To free memory I have to call delete[] while I cannot find an expression where I can call only simply delete.
I completely do not understand why this is a problem, but you could do it by wrapping your array inside another type... say std::array, boost::array or std::vector.
First of all, if your new expression has square brackets (new somtype[somesize]), your delete has to have square brackets as well (delete [] your_pointer).
Second, right now you've defined p_b to be a single pointer to some data. If what you really want is an array of pointers, then you need to define it as an array. Since you apparently want three independent arrays, you'll have to allocate each of them separately. It's probably easiest if you start with a typedef:
typedef int *p_int;
p_int p_b[3];
Then you'll allocate your three arrays:
for (int i=0; i<3; i++)
p_b[i] = new int[10];
To delete those, you'll need to delete each one separately:
for (int i=0; i<3; i++)
delete [] p_b[i];
I definitely agree with #Tomalak that you should almost never mess with things like this yourself though. It's not clear what you really want to accomplish, but it's still pretty easy to guess that chances are quite good that a standard container is likely to be a simpler, cleaner way to do it anyway.
Here's an example of how to implement Q1:
int main()
{
typedef int foo[10];
foo* f = new foo[3];
f[0][5] = 5;
f[2][7] = 10;
delete [] f;
}
As for Q2, the only way to delete memory allocated with new[] is with delete[]. If you personally don't want to write delete [], you can use a vector or another STL container. Really, unless this is some hardcore uber-optimisation, you should be using vectors anyway. Never manage memory manually unless you are absolutely forced to.
To use a raw pointer to manage a 2-d array you must first create a pointer to a pointer to array element type that will point to each row of the array. Next, each row pointer must be assigned to the actual array elements for that row.
int main()
{
int **p;
// declare an array of 3 pointers
p = new int*[3];
// declare an array of 10 ints pointed to by each pointer
for( int i = 0; i < 3; ++i ) {
p[i] = new int[10];
}
// use array as p[i][j]
// delete each array of ints
for( int i = 0; i < 3; ++i ) {
delete[] p[i];
}
// delete array of pointers
delete[] p;
}
A far easier solution is to use std::array. If your compiler does not provide that class you can use std::vector also.
std::array<std::array<int,10>,3> myArr;
myArr[0][0] = 1;
For Q1, I think you want
int (*p[3])[10];
Try cdecl when you're unsure.
Your other question seems to be well answered by other answers.
regards,
Yati Sagade
Actually, nobody posted an answer to your exact question, yet.
Instead of
int (*p_arr)[10] = new int[3][10];
// use, then don't forget to delete[]
delete[] p_arr;
I suggest using
std::vector<std::array<int, 10>> vec_of_arr(3);
or if you don't need to move it around and don't need runtime length:
std::array<std::array<int, 10>, 3> arr_of_arr;
Q1
How to declare p_b if I want that each element be a pointer to a fixed array size?
int(**pp_arr)[10] = new std::add_pointer_t<int[10]>[3];
for (int i = 0; i < 3; ++i)
pp_arr[i] = new int[1][10];
// use, then don't forget to delete[]
for (int i = 0; i < 3; ++i)
delete[] pp_arr[i];
delete[] pp_arr;
The modern variant of that code is
std::vector<std::unique_ptr<std::array<int, 10>>> vec_of_p_arr(3);
for (auto& p_arr : vec_of_p_arr)
p_arr = std::make_unique<std::array<int, 10>>();
or if you don't need to move it around and don't need runtime length:
std::array<std::unique_ptr<std::array<int, 10>>, 3> arr_of_p_arr;
for (auto& p_arr : arr_of_p_arr)
p_arr = std::make_unique<std::array<int, 10>>();
Q2
Is per my original code sample above, how to call new so that p_b points to a unique fixed-size array of 10 int other than calling p_b = new int[1][10]?
Not without wrapping the array into another type.
std::array<int, 10>* p_arr = new std::array<int, 10>;
// use, then don't forget to delete
delete p_arr;
You can replace std::array<int, 10> with your favourite array-wrapping type, but you cannot replace it with a fixed-size array alias. The modern variant of that code is:
auto p_arr = std::make_unique<std::array<int, 10>>();