Is this the right way to use a function that writes to a pointer? Do I have to allocate memory for the double* before calling the function?
double *myDouble;
write_to_pointer( myDouble );
Do you mean it writes to the pointer itself, or to the memory it points to?
If it's the first, and it takes the pointer by reference, for example:
void write_to_pointer(double *& p) {
p = whatever;
}
then it's correct, although rather confusing. It would be better to return the value as a return value, so that the assignment is more obvious:
double *get_pointer() {return whatever;}
double *myDouble = get_pointer();
If it's the second, then no: the pointer doesn't point at anything, so attempting to dereference it will give undefined behaviour (typically crashing or corrupting some other program memory). It will need to point to a valid double (or a sufficiently large array of double, if that's what the function expects).
You can make pointers point to data in a variety of ways.
The following will create a single double on the heap, and will be pointed to by myDub. It will then assign the value of myDub to 4. It will then delete myDub and set the pointer to NULL.
double * myDub = new double;
*myDub = 4;
delete myDub;
myDub = NULL;
You can similarly allocate arrays.
double * myDub = new double[123];
myDub[0] = 4;
myDub[3] = 43;
delete[] myDub;
myDub = NULL;
And you can have pointers point to variables that already exist. (Note that I don't call delete in this case!)
double onStack = 4;
double * myDub = &onStack;
This is the wrong way to write to a pointer. Either allocate memory to your variable:
double *myDouble = new double;
write_to_pointer( &myDouble );
delete myDouble;
in this case declaration will be write_to_pointer( double** )
OR
declare your variable on stack:
double myDouble;
write_to_pointer( &myDouble );
in this case declaration will be write_to_pointer( double* )
Related
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.
If i want to give a value to int *num2, how would i do this ?
#include <stdio.h>
int main(int argc, const char * argv[]) {
// insert code here...
struct az {
int num1;
int *num2;
};
struct az test;
test.num1 =20;
printf("\n %d",test.num1);
return 0;
}
int *num2; is a pointer to some place in the memory that contains an int value. Since you just declare a pointer without any memory allocating, it is simply points to nothing (or random place).
You have to allocate memory then assign a value to this memory:
test.num2 =new int(20);
However, do not forget to delete this allocated memory when you finish:
delete test.num2;
The real question here, do you really want that pointer here? probably not.
You can assign num2 in the same way as num1. Of course, since it's not an int but an int*, you can't assign 20 to it - you can assign the address of some int variable instead:
struct az {
int num1;
int *num2;
};
struct az test;
test.num1 = 20;
int i;
test.num2 = &i;
To assign a value to the integer that test.num2 points to, you must de-reference the pointer with an asterisk, like so:
test.num2 = new int(20); // Allocates memory and sets the pointer to this memory
*(test.num2) = 10; // Assign a value of 10 to the int that test.num2 points to
To assign an address to the pointer, you must either assign another pointer to it, or assign it's value by referencing an int with an ampersand:
test.num2 = new int(20); // Allocates memory and sets the pointer to this location
int *ptr = new int(10);
delete test.num2; // Free memory that test.num2 pointed to
test.num2 = ptr // Makes test.num2 point to the same int as ptr
int x = 10;
test.num2 = &x; // Makes test.num2 point to x
In your example num2 is typically used as a pointer to a dynamically allocated array. However, neither num2 nor num1 is a good name in this case. Let's instead declare our dynamic array type as a record with the fields length and items:
struct Array {
int length;
int *items;
};
typedef struct Array Array;
If we have a variable a of type Array, before we can assign values to its elements we must first allocate memory for the array. In C this is typically done with the function malloc. This function, however, is rather error prone to use so it's a good idea to define a macro function which simplifies memory allocation:
#define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof (ptr)[0])
After having called NEW_ARRAY we can assign values to the array:
int length;
Array a;
length = 20;
a.length = length;
NEW_ARRAY(a.items, length);
a.items[0] = 37;
a.items[1] = 19;
...
When we are done with the array we can release the memory used by the elements:
free(a.items);
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.
Any ideas for this typecasting problem?
Here's what I am trying to do. This is not the actual code:
LinkedList* angles;
double dblangle;
dblangle = (some function for angle calculation returning double value);
(double*)LinkedListCurrent(angles) = &double;
I hope you get the idea. The last line is causing the problem. Initially angles is void* type so I have to first convert it to double*.
You use the unary * operator to dereference a pointer. Dereferencing a pointer means extracting the value pointed to, to get a value of the original type.
// Create a double value
double foo = 1.0;
// Create a pointer to that value
double *bar = &foo;
// Extract the value from that pointer
double baz = *bar;
edit 2: (deleted edit 1 as it was not relevant to your actual question, but was based on a miscommunication)
From your clarification, it looks like you are wondering how to set a value pointed to by a pointer that has been cast from a void * to a double *. In order to do this, we need to use the unary * on the left hand side of the assignment, in order to indicate that we want to write to the location pointed to by the pointer.
// Get a void * pointing to our double value.
void *vp = &foo;
// Now, set foo by manipulating vp. We need to cast it to a double *, and
// then dereference it using the * operator.
*(double *)vp = 2.0;
// And get the value. Again, we need to cast it, and dereference it.
printf("%F\n", *(double *)vp);
So, I'm assuming that your LinkedListCurrent is returning a void * pointing to some element in the linked list that you would like to update. In that case, you would need to do the following:
*(double*)LinkedListCurrent(angles) = dbangle;
This updated the value pointed to by the pointer returned from LinkedListCurrent to be equal to dbangle. I believe that is what you are trying to do.
If you are trying to update the pointer returned by LinkedListCurrent, you can't do that. The pointer has been copied into a temporary location for returning from the function. If you need to return a pointer that you can update, you would have to return a pointer to a pointer, and update the inner one.
My explanation above is based on what I believe you are trying to do, based on the example snippet you posted and some guesses I've made about the interface. If you want a better explanation, or if one of my assumptions was bad, you might want to try posting some actual code, any error messages you are getting, and a more detailed explanation of what you are trying to do. Showing the interface to the linked list data type would help to provide some context for what your question is about.
edit 3: As pointed out in the comments, you probably shouldn't be casting here anyhow; casts should be used as little as possible. You generally should use templated collection types, so your compiler can actually do typechecking for you. If you need to store heterogenous types in the same structure, they should generally share a superclass and have virtual methods to perform operations on them, and use dynamic_cast if you really need to cast a value to a particular type (as dynamic_cast can check at runtime that the type is correct).
why on earth would you want to use a memory address as a floating point number?
if you meant dereference:
double d = 1.0; // create a double variable with value 1.0
double *dp = &d; // store its address in a pointer
double e = *dp; // copy the value pointed at to another variable
Note this line:
(double*)LinkedListCurrent(angles) = &double;
where you've written &double, it i think should be &dbangle. To improve readability, I would write:
((double*)LinkedListCurrent(angles)) = &dbangle;
However, you should not do this type of conversion as others mentioned.
Use a union. If you want the store two variables in one memory location (but not at the same time), you don't have to pretend that one is the other.
union double_and_ptr {
double d;
double *p;
};
double_and_ptr x, y;
x.d = 0.1;
y.p = &x.d; // store a pointer in the same place as a double
y.d = x.d * 1.2; // store a double in the same place as a ptr
Use reinterpret_cast.
double foo = 3.0;
double* pfoo = &foo;
double bar = reinterpret_cast<double>(pfoo);
In answer to this:
I want to do the opposite of what you have done here. I want to copy the value from the pointer to the d floating point number. How can I do that?
You would do something like this:
// declare a pointer to a double
double *pointer_to_double;
// declare a double
double my_double = 0.0;
// use the indirection operator (*) to dereference the pointer and get the value
// that it's pointing to.
my_double = *pointer_to_double;
This might be done like so in a real program:
void print_chance_of_snow(double *chance)
{
double d = *chance;
d = d * 100; // convert to a percentage
printf("Chance of snow is: %.2f%%\n", d);
}
int main(int argc, char *argv[])
{
double chance_of_snow = 0.45;
print_chance_of_snow(&chance_of_snow);
}
I am declaring an array of void pointers. Each of which points to a value of arbitary type.
void **values; // Array of void pointers to each value of arbitary type
Initializing values as follows:
values = (void**)calloc(3,sizeof(void*));
//can initialize values as: values = new void* [3];
int ival = 1;
float fval = 2.0;
char* str = "word";
values[0] = (void*)new int(ival);
values[1] = (void*)new float(fval);
values[2] = (void*)str;
//Trying to Clear the memory allocated
free(*values);
//Error: *** glibc detected *** simpleSQL: free(): invalid pointer: 0x080611b4
//Core dumped
delete[] values*;
//warning: deleting 'void*' is undefined
//Similar Error.
Now how do I free/delete the memory allocated for values ( the array of void pointers)?
I suspect the issue is with the way that you allocated values: values = (void*)calloc(3,sizeof(void)). That should be sizeof(void *) rather than just sizeof(void).
sizeof(void) may be zero or something else that makes no sense, so you're not really allocating any memory to begin with... it's just dumb luck that the assignments work, and then the error pops up when you try to deallocate the memory.
EDIT: You're also asking for trouble by alternating between C++-style new/delete with C-style malloc/free. It is okay to use them both as long as you don't delete something you malloc'ed or free something you new'ed, but you're going to mix them up in your head if you go like this.
You have 3 things that are dynamically allocated that need to be freed in 2 different ways:
delete reinterpret_cast<int*>( values[0]);
delete reinterpret_cast<float*>( values[1]);
free( values); // I'm not sure why this would have failed in your example,
// but it would have leaked the 2 items that you allocated
// with new
Note that since str is not dynamically allocated it should not (actually cannot) be freed.
A couple of notes:
I'm assuming that the sizeof(void)
was meant to be sizeof(void*)
since what you have won't compile
I'm not going to say anything about
your seemingly random casting except
that it looks like code that ready
for disaster in general
This is the perfect situation for the boost::any class
Also you may want to consider using a vector rather than allocating your own memory.
std::vector<boost::any> data;
boost::any i1 = 1; // add integer
data.push_back(i1);
boost::any f1 = 1.0; // add double
data.push_back(f1);
data.push_back("PLOP"); // add a char *
std:: cout << boost::any_cast<int>(data[0]) + boost::any_cast<double>(data[1])
<< std::endl;
Going back to your original code the main problem was:
values = (void*)calloc(3,sizeof(void));
// This should have been
void** values = (void**)calloc(3,sizeof(void*));
// Freeing the members needs care as you need to cast them
// back to the correct type before you release the memory.
// now you can free the array with
free(values);
Also note: Though it is not illegal to use both new/delete and calloc/free in the same piece of code it is frowned upon. Mainly because it is easy to get things mixed up and that could potentially be fatal.
You're mixing new and *alloc(). That's a no-no, and can lead to undefined results.
I'm not sure why you are using new if you're doing things in C (referencing the tag here).
I would malloc the individual pieces of the array I need and then free them when I'm done I suppose. You can't free something you didn't first malloc. You also can't delete a void pointer.
Note that you're also not deleting values[0] and values[1] which is a memory leak, Yet by your design you can't free values[2] since its a pointer into you .data section.
You'd have to keep track of how many void* were originally calloc'd, and iterate over them, free-ing each one, then free the original values variable.
darn formatting... (the preview is working fine).
int ct = 3;
values = (void*)calloc(ct,sizeof(void));
//can initialize values as: values = new void* [3];
int ival = 1;
float fval = 2.0;
char* str = "word";
values[0] = (void*)new int(ival);
values[1] = (void*)new float(fval);
values[2] = (void*)str;
for ( int i = 0; i < ct; i++ ) [
delete( values[i] );
}
free( values );