confusion with passing arrays by reference using pointers - c++

I just asked a question several hours ago, and I have been utterly confused with something pointed out in the answers (arrays using pointers in c++: segmentation fault when accessing the returned array). Some people have been responding a bit negatively to my newb questions, so I went over my book about pointers, which did not help me much. So, here I go again.
In the previous question, I had a function void builder(int aSize1, int aSize2, int aSize3, int*** frequencies) that I thought would dynamically allocate memory for the 3d array passed in for the int*** frequencies parameter and initialize it. However, I was told that only a copy would be passed into the function and I would be allocating and initializing just for the copy not the original. Hence, they have advised me to use a reference instead, rendering the function prototype as void builder(int aSize1, int aSize2, int aSize3, int***& frequencies).
However, I recalled that just yesterday when I first stumbled upon this concept of pass by reference using pointers, one would be able to manipulate the data of the pointer as well. To wit,
void change_what_this_points_to( int* a )
{
*a = 42;
}
this function does change the value of a pointer that is fed into the function.
So, my question is, why does the former pass in a copy while the latter passes the real deal? I do not see much difference between the two functions, aside from the fact that one has more asterisks.
Any help would be appreciated. Thanks!

While the other answer says it perfectly I just thought I'd add my two cents just in case it helps. Think of a pointer as just an address in memory. You pass that address into a function, and the function writes something in there. Then after the function is called you can look in that same location in memory and see what value is there.
So let's assume you have the following code:
void SetValue(int *a){ *a = 10;}
void DoWork()
{
int a;
SetValue(&a);
}
The SetValue function takes as a parameter a pointer to an int, or as we'll think of it, an address in memory where an int is stored. The function then simply writes the number 10 to the passed in address.
The method DoWork then creates the memory for an int and passes the address of that memory to the function. So by the time DoWork returns the memory where "a" is stored has the value 10. Sounds like you have this already from your question but wanted to start here just in case.
Now let's pretend you want a function to allocate memory for you. What you are really asking the function to do is to allocate memory and tell me where that memory is. So you could do that with a pointer return value, i.e.
int* AllocateMemoryForMe()
{
return new int(); //Creates memory for an int, let's pretend it's at location 0x100
}
void DoWork()
{
int* a = NULL; // a has a value of 0x00
a = AllocateMemoryForMe(); //a will now have the value of 0x100
*a = 10; //We now write 10 to memory location 0x100
}
Or you could do this using a pointer. If you do this, what you actually have to do is pass into the function a location in memory to write the address of the allocated memory into, so a pointer to a pointer. So when the function returns you can look into this address and see what the address of newly created memory is. So for example:
void AllocateMemoryForMe(int** x)
{
*x = new int(); //allocates memory for an int, let's pretend it's at memory location 0x200
}
void DoWork()
{
int** a = new int*(); //Creates memory for an int pointer. Let's pretend it allocates memory at location 0x100.
AllocateMemoryForMe(a); //pass memory location 0x100 to the function.
//Right now the address of a is still 0x100 but the data at the memory location is 0x200. This is the address of the int we want to write to.
**a = 10; //This will now write 10 to the memory location allocated by the AllocateMemoryForMe() function.
}

This function
void change_what_this_points_to( int* a )
{
*a = 42;
}
does not change the pointer itself. It changes the integer object pointed to by the pointer.
If you want to change the pointer itself you should write the function either the following way
void change_what_this_points_to( int * &a )
{
a = new int( 42 );
}
or the following way
void change_what_this_points_to( int **a )
{
*a = new int( 42 );
}
Thus returning to your function you should declare it either like
void builder(int aSize1, int aSize2, int aSize3, int*** &frequencies);
or like
void builder(int aSize1, int aSize2, int aSize3, int**** frequencies);

Related

Difference between creating a pointer with 'new' and without 'new' apart from memory allocation?

What is the difference between these pointers?
I know that this one is going to be stored on the heap, even though a pointer is only 8 bytes anyways, so the memory is not important for me.
int* aa = new int;
aa = nullptr;
and this one is going to be stored on the stack.
int* bb = nullptr;
They both seem to work the same in my program. Is there any difference apart from memory allocation? I have a feeling that the second one is bad for some reason.
2) Another question which is somewhat related:
Does creating a pointer like that actually take more memory? If we take a look at the first snippet, it creates an int somewhere (4 bytes) and then creates a pointer to it (8 bytes), so is it 12 bytes in total? If yes are they both in the heap then? I can do this, so it means an int exists:
*aa = 20;
Pointers are integers that just indicate a memory position, and a type (so they can only point to variables of that type).
So in your examples, all pointers are stored in the stack (unless they are global variables, but that is another question). What they are pointing to is in the heap, as in the next example.
void foo()
{
int * ptr = new int(42);
// more things...
delete ptr;
}
You can have a pointer pointing into the stack, for example, this way:
void foo()
{
int x = 5;
int * ptr = &x;
// more things...
}
The '&' operator obtains the memory position of the variable x in the example above.
nullptr is the typed equivalent to old NULL. They are a way to initialize a pointer to a known and secure value, meaning that they are not pointing to anything else, and that you can compare whether they are NULL or not.
The program will accept pointers pointing to the stack or the heap: it does not matter.
void addFive(int * x)
{
*x += 5;
}
void foo()
{
int x = 5;
int * ptr1 = &x;
int * ptr2 = new int(42);
addFive( ptr1 );
addFive( ptr2 );
addFive( &x );
printf( "%d\n", *ptr1 );
printf( "%d\n", *ptr2 );
// more things...
delete ptr2;
}
The only difference is that the C runtime will keep structures telling how much memory has been spent in the heap, and therefore storing variables in the heap comes at a cost in performance. On the other hand, the stack is always limited to a fixed amount of memory (relatively small), while the heap is much larger, allowing you to store big arrays, for example.
You could take a look at C-Sim, which simulates memory in C (disclaimer: I wrote it).
Hope this helps.

Save memory data from function pointers c++

I do have a function and I need it to be of void type and to pass and get back its pointers:
void cracking::decompose(char input[][100], int size_S, double* &Atm, int* &ID, int &size_out);
{
vector<double> AtmD;
vector<int> XsD;
...
Atm = &AtmD[0];
ID = &XsD[0];
size_out = size(AtmD);
}
My Idea here is to get the address of the first value of the Vectors and with its size I may be able to get all the values, however when I call it in the main function it builds but the data in this memory adress is deleted and I get only garbage. Is there a way that I Maintain the data associated to these pointers?
here is how the function is called in the main:
int main()
{
char oi[900][100] = { "1 0.5 C", "2 0.55 N", "3 .5 S" };
double* xAtm = NULL;
int* xXs = NULL;
int tamanho;
cracking calc;
calc.decompose(oi, 3, xAtm, xXs, tamanho);
return 0;
}
Local variables will disappear after execution leaves the function. You can't return their address because deleted objects don't have an address.
The compiler may use registers for the local variables. Registers don't have useful addresses.
If you want to return the address of a variable, declare it as static:
double * some_function(void)
{
static double pi = 3.14159264;
return π
}
Another alternative is to declare the variable in dynamic memory and return the pointer:
double * another_function()
{
double * p_pi = new double(3.14159264);
return p_pi;
}
I think I understand your question, but i'm not entirely sure. I am assuming you are asking about returning the pointers to a few local variables inside of another function. I think something that you need to understand here is how the stack works. When you call your decompose function, you create a new frame on the stack, with a return address to main. All the local variables will be pushed onto the stack. Once the decompose function returns, that stack space is free to be reused again.
Is there a way that I Maintain the data associated to these pointers?
Yes! Allocate your variables on the heap. Look up new in C++. Hope this helps point you in the right direction!

Which data type does pointer points to?

I am kind of confused with the pointers.
Say if I have this:
int size;
int bytes;
int numbers;
int *ptr;
ptr = new int[500];
My question is the pointer at first points to any specific variable or just to overall int variables. What if I want a pointer to point only at numbers variable.
I have a tail question if you don't mind. I am trying to allocate dynamic memory to my array, is this valid? :
int numbers[20];
int *ptr;
ptr = new int[size];
Would this give a heap memory to my array?
I am working with an array of very large size and there is no other way to work with it without using heap memory.
P.S: I can't use vector at this point.
int *ptr is an pointer to an int variable. It doesn't matter what variable, as long as it is an int so you could have the following.
int size;
int bytes;
int numbers;
int *ptr;
ptr = &size;
ptr = &bytes;
ptr = &numbers;
I use the & symbol because this gives the actual address of the variable not its value. Pointers can only store the address of a variable.
If you then wanted to use the actual values that the pointer points to, you need to deference it, like so
int number = 5;
int *ptr;
ptr = &number;
cout << *ptr;
//5
As for your second question. Yes that would give you a valid pointer to an array on the heap.
For more information I suggest looking up what an array actually is, since you might be confused why you don't need to use the & symbol when assigning a pointer to an array.
int *ptr is uninitialized, so it actually points to "garbage values" or in this case, random memory addresses. Check out Uninitialized pointers in code
If you want int *ptr to point to the value of numbers, you should first initialize int numbers, because this can cause Undefined behavior if you try to dereference it.
You can assign the ptr equal to numbers by using the Address-of operator &. Then use the dereference operator * to grab the value of ptr.
numbers = 4;
ptr = &numbers;
cout << *ptr << endl;
This will print 4.
int arNumbers[20];
gives you memory from stack and is not dynamic and compiler would take care of releasing the memory.
int *pNumbers = new int[20];
gives you memory from heap and is dynamic and you need to delete it when you are done:
delete[] pNumbers;
if you need 20 numbers, one of them is enough.

Why pointer to pointer?

A very general question: I was wondering why we use pointer to pointer?
A pointer to pointer will hold the address of a pointer which in turn will point to another pointer. But, this could be achieved even by using a single pointer.
Consider the following example:
{
int number = 10;
int *a = NULL;
a = &number;
int *b = a;
int *pointer1 = NULL;
pointer1 = b; //pointer1 points to the address of number which has value 10
int **pointer2 = NULL;
pointer2 = &b; //pointer2 points to the address of b which in turn points to the address of number which has value 10. Why **pointer2??
return 0;
}
I think you answered your own question, the code is correct, what you commented isn't.
int number = 10; is the value
int *pointer1 = b; points to the address where int number is kept
int **pointer2 = &b; points to the address where address of int number is kept
Do you see the pattern here??
address = * (single indirection)
address of address = ** (double indirection)
The following expressions are true:
*pointer2 == b
**pointer2 == 10
The following is not!
*pointer2 == 10
Pointer to pointer can be useful when you want to change to what a pointer points to outside of a function. For example
void func(int** ptr)
{
*ptr = new int;
**ptr = 1337;
}
int main()
{
int* p = NULL;
func(&p);
std::cout << *p << std::endl; // writes 1337 to console
delete p;
}
A stupid example to show what can be achieved :) With just a pointer this can not be done.
First of all, a pointer doesn't point to a value. It point to a memory location (that is it contains a memory address) which in turn contains a value. So when you write
pointer1 = b;
pointer1 points to the same memory location as b which is the variable number. Now after that is you execute
pointer2 = &b;
Then pointer2 point to the memory location of b which doesn't contains 10 but the address of the variable number
Your assumption is incorrect. pointer2 does not point to the value 10, but to the (address of the) pointer b. Dereferencing pointer2 with the * operator produces an int *, not an int.
You need pointers to pointers for the same reasons you need pointers in the first place: to implement pass-by-reference parameters in function calls, to effect sharing of data between data structures, and so on.
In c such construction made sense, with bigger data structures. The OOP in C, because of lack of possibility to implement methods withing structures, the methods had c++ this parameter passed explicitly. Also some structures were defined by a pointer to one specially selected element, which was held in the scope global to the methods.
So when you wanted to pass whole stucture, E.g. a tree, and needed to change the root, or 1st element of a list, you passes a pointer-to-a-pointer to this special root/head element, so you could change it.
Note: This is c-style implementation using c++ syntax for convienience.
void add_element_to_list(List** list, Data element){
Data new_el = new Data(element); // this would be malloc and struct copy
*list = new_el; //move the address of list, so it begins at new element
}
In c++ there is reference mechanismm and you generally you can implement nearly anything with it. It basically makes usage of pointers at all obsolete it c++, at least in many, many cases. You also design objects and work on them, and everything is hidden under the hood those two.
There was also a nice question lately "Why do we use pointers in c++?" or something like that.
A simple example is an implementation of a matrix (it's an example, it's not the best way to implement matrices in C++).
int nrows = 10;
int ncols = 15;
double** M = new double*[nrows];
for(unsigned long int i = 0; i < nrows; ++i)
M[i] = new double[ncols];
M[3][7] = 3.1416;
You'll rarely see this construct in normal C++ code, since C++ has references. It's useful in C for "passing by reference:"
int allocate_something(void **p)
{
*p = malloc(whatever);
if (*p)
return 1;
else
return 0;
}
The equivalent C++ code would use void *&p for the parameter.
Still, you could imagine e.g. a resource monitor like this:
struct Resource;
struct Holder
{
Resource *res;
};
struct Monitor
{
Resource **res;
void monitor(const Holder &h) { res = &h.res; }
Resource& getResource() const { return **res; }
}
Yes, it's contrived, but the idea's there - it will keep a pointer to the pointer stored in a holder, and correctly return that resource even when the holder's res pointer changes.
Of course, it's a dangling dereference waiting to happen - normally, you'd avoid code like this.

Why would a change in a function header cause a Pointer assignment to not function?

When I change the last parameter in the function header from char Findthis[64] to char * Findthis when debugging the Testthis=&*Look_in; assignment breaks. Look_in has a memory address and member values but Testthis is not being assigned that pointer location. Why is this happening?
struct Node * ProbableMatch(struct Node * Look_in, int MaxNodes,
char Findthis[64])
{
char Findit[64];
strcpy_s(Findit,64,Findthis);
struct Node * CurrentHighProb;
CurrentHighProb=new(Node);
struct Node * Testthis;
Testthis=new(Node);
Testthis=&*Look_in;
while((Testthis) || (i!=(ccounter-1)))
{ //This Testthis does not cause exception
string str1;
string str2;
n1=sizeof(Testthis->NAME);
n2=sizeof(Findit);
n=0;
while((Testthis->NAME[n]!='\0') && (n<=n1)){
//While Testthis->NAME here causes the exception
if(Testthis->NAME[n]=='-'){Testthis->NAME[n]=' ';}
n++;
}//end of while
//_DIFFERENT PART OF PROGRAM____
std::string Findme;
cout<<"Enter varible to find. Type quit to quit, case sensative."<<endl;
cin>>Findme;
char * writable = new char[Findme.size()+1];
std::copy(Findme.begin(),Findme.end(),writable);
writable[Findme.size()] = '\0';
if((Findme.compare("quit")!=0) ^ (Findme.compare("Quit")!=0) ^ (Findme.compare("QUIT")!=0)){
ProbableMatch(head,ccounter,writable);
}
delete [] writable;
//_ NODE____
struct Node
{ public:
int VARID,counter,prob;
char NAME[64];
char DESCRIPTION[1024];
struct Node* next;
}node, *pNode=&node;
Looks more like C code. Why are you using C-strings and std strings? In any case, it looks like your error is unrelated. The assignment before Testthis = &*Look_in is useless (not to mention the new call leaks memory). In this case, there is no reason to first dereference your Look_in node and then take the address. You should be able to simply change that statement to Testthis = Look_in.
However, if this is a runtime error, be certain that Look_in != NULL or is not deleted somewhere else.
It looks like you have small confusion on pointers overall; so here is a quick run-down.
Pointers point to a memory location at which some value is stored. So when you declare a pointer and assign it some memory location, you are telling that pointer where in memory to look for some item. When you dereference a valid, non-null pointer, you can get the value which that memory location holds. For instance,
Node x[64]; // An array of 64 nodes
Node * t = x; // t points to element 0 of x. Therefore, changing values of x changes values of t and changing values of t changes values of x
Furthermore, memory allocation/deallocation is a different story. Stack memory (as declared above for both of those declarations) is managed by the operating system. However, heap allocation is up to you (i.e. new/delete).
Node * x = new Node;
// Do stuff with your node - it is on the heap, so it is persistent until you explicitly remove it
delete x;
The biggest difference between the stack and the heap is that heap memory exceeds the life of the function. For example, each function gets its own stack-frame to declare variables on. However, when the function exits, then the stack-frame is freed. Heap memory, however, can hold values which are not exclusive to a single function lifetime.
A simple example is this:
int* giveMeAnInt()
{
int x;
return &x;
}
In the function above, we declare a local variable, and try to return its address as a pointer to that value. However, after we return, that value is popped off the stack anyway since the function has ended. To do this properly you would have to:
int* giveMeAnInt()
{
int* x = new int;
return x;
}
The second example declares a variable on the heap and returns its address. But do not forget, if you use new, you must delete it later. Another quick example (using the working version of the code above i.e. example 2)
...
int * z = giveMeAnInt();
cout<< *z << endl;
delete z; // Free the memory allocated by the giveMeAnInt() function
...
That is a lot of quick information, but good luck.
EDIT
Perhaps if you are crashing at ...->NAME[n], then NAME[n] does not exist. Notice that you are effectively dereferencing Testthis at sizeof(Testthis->NAME) so the problem is not with the pointer. If you are looking for the number of characters in the string for a pointer, then you must use strlen() and not sizeof().
Here is the problem we are facing: the difference between an array and a pointer. If you declare char someArray[64], then sizeof(someArray) == 64. However, if you declare char* someArray, then sizeof(someArray) == 4 (since sizeof(char*) == 4, assuming 32-bit machine. But for now, the constant doesn't matter) and not the actual number of characters. To be safe, you should instead simply use strlen(someArray) which will work as expected for both declarations.
Ok looks like the std::string to char * conversion was causing leaks.
Switched to a vector option as suggested here: How to convert a std::string to const char* or char*?
Problem went away. I'll have to trace the actual memory later but I find it odd that that string memory was placed right next to the begining of the linked-list.