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

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.

Related

Double pointer array in c++

I was reading a program about BTree, there I came across this : BTreeNode **C. I understand that it is a 2d array but it was initialized as C=new BTreeNode *[2*t];. I can't understand this: is this a 2d array with dynamic rows and 2t columns ?
Thanks.
You probably well know that double* is a pointer to a double element. In the same way, double** is a pointer to a double* element, which is itself a pointer. Again, double*** is a pointer to a double** element, and so on.
When you instanciate an array to a type T, you usually do new T [size];. For example, for an array of double, you write new double[size];. If your type T is a pointer itself, it's exactly the same : you write new double*[size];, and you get an array of pointers.
In your case, BTreeNode* is a pointer to BTreeNode, and BTreeNode** is a pointer to BTreeNode* which is a pointer to BTreeNode. When you instanciate it by doing new BTreeNode*[size]; you get an array of pointers to BTreeNode elements.
But actually, at this step you don't have a 2D array, because the pointers in your freshly allocated array are NOT allocated. The usual way to do that is the following example :
int num_rows = 10;
int num_cols = 20;
BTreeNode** C = new BTreeNode*[num_rows];
for(int i = 0; i < num_rows; i++)
{
// Then, the type of C[i] is BTreeNode*
// It's a pointer to an element of type BTreeNode
// This pointer not allocated yet, you have now to allocate it
C[i] = new BTreeNode [num_cols];
}
Don't forget to delete your memory after usage. The usual way to do it is the following :
for(int i = 0; i < num_rows; i++)
delete [] C[i];
delete [] C;
The statement C=new BTreeNode *[2*t]; allocates space for 2*t instances of type BTreeNode * and therefore returns a type BTreeNode ** pointing to the first element of such instances. This is the first dimension of your array, however no memory has been allocated for the second dimension.
Yes. If the array is being indexed column-major order (so C[3][4] is the 5th element of the 4th column) then C could, potentially, have ragged (differently sized) columns.
Look for some code that allocates memory for each column, i.e.
C[i] = new BTreeNode[length];
in a loop over i, that would indicate that the 2D array has the same length per column.

How to create an array of pointers without using vector

I saw that an array of pointers can be created using vector, however, I don't want that. Is the example below a way to create a pointer to int array?
#include <iostream>
using namespace std;
int main() {
int* arr[4];
for (int i=0; i<4; ++i) {
cout<<endl<<arr[i];
}
}
This makes a pointer to int array and it displays the memory address of each index in the array. Now I have few questions. Is it a proper way to create a pointer to int array without a vector? Also, if I want to initialize a value inside each memory address in the given example, how is it done? And lastly why is &arr equal to arr?
While &arr and just plain arr may both give you the same address, they are both very different.
With &arr you get a pointer to the array, and the type of it is (in your case) int* (*)[4].
When you use arr it decays to a pointer to the first element and the type is (again, in your case) int**.
Same address, but different types.
As for the array itself, it's defined fine, you have an array of four pointers to int. However, you do not initialize the contents of the array, which means that the contents is indeterminate, and using those pointers in any way (even just printing them) leads to undefined behavior.
Your proposed way doesn't make pointer to int array. Instead of that it makes a pointer to pointer to an int array. Usually the name of any array represent a pointer to it self. Or &arr[0] also represent it.
So I hope that you got the answer for why &arr equal arr.
Creating a pointer to int array
int arr[4];
int* p = arr; //pointer to int array
Initializing each element in array
(1) Using pointer arithmetic
int size = 4;
int* p = arr;
for (int i = 0; i < size; i++)
{
*p = i; // assigning each element i
p++; //pointing to next element
}
(2) Using operator []
int size = 4;
for (int i = 0; i < size; i++)
{
arr[i] = i; // assigning each element i
}
&arr gives you the address of array which starts with base address ie address of first element.
arr gives the address of first element.
hence u get same result for both

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

The correct way to initialize a dynamic pointer to a multidimensional array? [duplicate]

This question already has an answer here:
How to properly work with dynamically-allocated multi-dimensional arrays in C++ [duplicate]
(1 answer)
Closed 7 years ago.
I've been having bad luck with with dynamic pointers when I range them to 2 dimensions and higher. For example I want a pointer to a 2D array. I know that:
int A[3][4];
int (*P)[4] = A;
Is completely legit (even if I don't completely understand why). Taking into consideration that:
int *P = new int[4];
works, I imagined that:
int **P = new int[5][7];
Would also work, but it's not. This code states the error:
Error: A value of type "(*)[7]" cannot be used to initialize an entity of
type "int **"
By seeing this the new part becomes a pointer to an array of 7 integers I made:
int (*P)[4] = new int[7][4];
And this does work but it's not what I want to accomplish. By doing it like that I'm limited to at least using a constant value for any subsequent dimension, but I want it to be fully defined at run time and therefore "dynamic".
How could I go and make this multidimensional pointer work??
Let's start with some basic examples.
When you say int *P = new int[4];
new int[4]; calls operator new function()
allocates a memory for 4 integers.
returns a reference to this memory.
to bind this reference, you need to have same type of pointer as that of return reference so you do
int *P = new int[4]; // As you created an array of integer
// you should assign it to a pointer-to-integer
For a multi-idimensional array, you need to allocate an array of pointers, then fill that array with pointers to arrays, like this:
int **p;
p = new int*[5]; // dynamic `array (size 5) of pointers to int`
for (int i = 0; i < 5; ++i) {
p[i] = new int[10];
// each i-th pointer is now pointing to dynamic array (size 10)
// of actual int values
}
Here is what it looks like:
To free the memory
For one dimensional array,
// need to use the delete[] operator because we used the new[] operator
delete[] p; //free memory pointed by p;`
For 2d Array,
// need to use the delete[] operator because we used the new[] operator
for(int i = 0; i < 5; ++i){
delete[] p[i];//deletes an inner array of integer;
}
delete[] p; //delete pointer holding array of pointers;
Avoid memory leakage and dangling pointers!
You want something like:
int **P = new int*[7];
p[0] = new int[5];
p[1] = new int[5];
...
Another approach would be to use a 1D array as an 2D array. This way you only have to allocate the memory once (one continous block);
int *array;
size_t row=5,col=5;
array = (int*)malloc(row*col*sizeof(int)) //or new int[row*col]
This would result in the same as "int array[5][5]".
to access the fields you just do:
array[1 //the row you want
* col //the number of columns
+2//the column you want
] = 4;
This is equal to:
array[1][2];
This performs bounds checking on some debug compilers, uses dynamic size and deletes itself automatically. The only gotcha is x and y are the opposite way round.
std::vector<std::vector<int>> array2d(y_size, std::vector<int>(x_size));
for (int y = 0; y < y_size; y++)
{
for (int x = 0; x < x_size; y++)
{
array2d[y][x] = 0;
}
}

How to access the array from the pointer?

I am trying to understand how pointers work but I do not know how a pointer to only the first element can be used to access all the array
int myArray[10];
for(int i=0; i<10; i++)
{
myArray[i] = 11*i;
}
int *p;
p = myArray;
//Now how do I access the complete array using the variable p
cout<<*p; //This only prints the first value, how to print all the values
You have to use while or for.
int i = 0;
while (i < 10)
{
cout << p[i];
i += 1;
}
Pointers and arrays are working in the same way. An array is nothing else than a pointer to the first element you allocated.
If you for example want to access pos 5, you can just write:
...
int *p;
p = myArray;
cout << p[5];
Since the compiler know that p is a pointer to an int, it will add the size of an int for each step (4 bytes in this case).
As long as you don't use pointers to void, the compiler does this for you.
You still have to keep track of the length of the array so you do not exceeds it since a pointer don't do that.
except for thr declaration, arrays and pointers con be used using the same syntax
(They are different in memory, meaning they still need to be treated differently)
Use like this,
int *p;
p = myArray;
for(int i=0;i<10;i++)
{
cout<<*(p+i);
}
The first element points to the first memory location of the elements in the array. So this:
myArray[0];
and
myArray;
point to the same location. You can use indexes on the pointer, just like you did to fill the array. So this:
int *p = myArray;
cout << p[0];
cout << p[1];
would access your other elements. You can use a for loop to access all the elements in the array, just like you did to populate it in the first place.
You can think of the name of an array as a pointer to its first element.
So, the line p = myArray; is simply copying the address of the first element of the array myArray into p.
Now the line cout<<*p; is obviously displaying the value of what's pointed by p, which is the first element of your array.
To display all the elements, you can simply use a for loop like you did before.