c++ how to make pointers point to arrays? - c++

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

Related

C++ Dynamic Array allocation in Classes

I am currently learning basics of c++, and am coming across an issue with the class array below.
class Arrayclass {
private:
int arraySize;
float array[];
public:
Arrayclass(int arraySize) {
float * array = new float[arraySize]();
}
~Arrayclass() {
delete[] array;
}
}
As far as I am aware, I am having issues with the array being initialized in the constructor not actually corresponding to a stored array in the new class, thus when I am initializing a new class in my main, the array created holds 0 values. I apologize my explanation is unclear, just trying to understand how the array initialized in the constructor correlates to the array in my private.
float array[]
either is an extension or just doesn't compile. For a C-style static array, Type name[constexpr_size] is used. For a dynamic array, Type* name is stored as a pointer to the beginning of the storage allocated.
Dynamic Array
OK, we need the second option. Then, we start with your snippet
class Array { // "class Arrayclass" -> "class Array", no need to repeat ourselves
private:
float* array{};
int size{}; // "Array::arraySize" -> "Array::size", again
public:
~Array() { delete[] array; } // your destructor is fine
};
(see member initializer as an explanation to those {} initializers in float* array{} and int size{}).
What about
Arrayclass(int arraySize) { float * array = new float[arraySize](); }
, you create a local float* which dies at the end of scope (=the constructor). You probably meant to store that newly allocated array in (this->)array:
Array(int newSize) { // BAD CODE, see below
array = new float[newSize]{};
size = newSize;
}
but the code above is like writing float* p; p = something (create default, than initialize it) instead of float* p{something} (initialize on creation), let's improve it by using member initializer list:
Array(int newSize): array{new float[newSize]{}}, size{newSize} {}
Now, your array (almost) can construct and destruct properly.
==========
However, there's still an issue left: code such as
{
Array a1{42};
Array a2{a1}; // copy construction
}
has undefined behavior and in practice (in this case) should/might crash your application. Why? Because it works as something like (sizes omitted):
{
float* array1{new float[42]{}};
float* array2{array1};
delete[] array1;
delete[] array2; // that UB (double free); the same dynamic array is deleted twice
}
Well, it is a topic for another "lesson". See the rule of three (five) (zero). In general, see RAII and copy/move-semantics.

Appending struct by reference to an array in C++

How can I implement a function in C++ that appends a struct instance to an array by reference? So that after appending a struct stored in a variable to the array, this variable can be used further to change the instance of array.
pseudocode:
struct St{
int x
}
St* arr;
St a = {0};
append a to arr;
a.x = 1;
//expecting arr[0].x = 1
Here is the C++ code with the film example (see comments describing the problem):
struct Film{
int id;
char* name;
};
void add_film(Film *&films, int &size, Film &film){
if (size == 0)
films = new Film[1];
else
{
Film *tmp = new Film[size + 1];
for (int i = 0; i < size; ++i)
{
tmp[i] = films[i];
}
delete[]films;
films = tmp;
}
films[size] = film;
film = films[size]; //how to reassign passed film object to a new object in array?
size++;
}
int main(){
Film *films = nullptr;
int size = 0;
Film film = {1, "Name1"};
add_film(films, size, film);
film.name = "Name2";
std::cout << films[0].name; //output: "Name1", expected: "Name2"
}
Appending struct by reference to an array in C++
There are two problems with this:
There cannot be arrays of references in C++.
There is no way to append to an array. The size of an array is a constant. There is no way to add or remove elements.
An issue with your attempted solution is that you have an array of Films, and not an array of references. This isn't very surprising, as problem 1 described above states there are no such thing as arrays of references. The solution is simple however: Use pointers instead of references. Technically, you could use a reference wrapper instead, but a pointer is often simpler.
You've basically figured out the solution to 2. already. What you're doing is creating a new array, copying the old elements from the old array into the new one, and destroying the old array. That's a good approach in general, but there are a number of problems with this trivial implementation:
Bare owning pointers are unsafe and hard to use.
Reallocating and copying the entire array on every append is very expensive.
Former can be solved by using the RAII idiom, and latter can be solved by separating the storage of the objects from the creation of the objects, and by growing the storage by a constant factor i.e. geometrically. There is no need to implement such RAII container though, since the standard library has you covered. It's called std::vector.
In conclusion: You can use std::vector<Film*>.

memcpy from a vector to void pointer (vice-versa) not working

This is struct node with 2 variables.
typedef struct{
int a;
int b;
}node;
Inserting the values into vector of the node type.
vector <node> nv;
node n;
n.a = 10;
n.b = 20;
nv.push_back(n);
n.a = 100;
n.b = 200;
nv.push_back(n);
Copying the vector to a void pointer.
void *ptr = malloc(4096);
memcpy((char*)ptr,&nv,sizeof(node)*2);
Reading the values from the void pointer
node *temp;
temp = (node*)malloc(sizeof(node));
int offset = 0;
i = 0;
while(i<n){
memcpy((node*)temp,(char*)ptr + offset, sizeof(node));
cout<<"a - "<<temp->a<<" b -"<<temp->b<<endl;
offset += sizeof(node);
i++;
}
I am printing the values of a and b. But they are incorrect and contains random numbers. I am sure that I am hitting the wrong memory location. But not sure where.
std::vector object is not an array object. The vector manages a dynamically allocated array. Just like your ptr isn't an array, but simply points to one.
Just like you musn't pass &ptr to malloc (as that would cause the data to be written over the pointer, not the pointed array), so too you musn't pass &nv (as that would cause the data to be read from vector which manages the array, rather than from the array which is being managed). Vector has a member function data which returns a pointer to the internal array.

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];

Using structures and pointer arrays 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;