I'm reading some code in the Ogre3D implementation and I can't understand what a void * type variable means. What does a pointer to void mean in C++?
A pointer to void, void* can point to any object:
int a = 5;
void *p = &a;
double b = 3.14;
p = &b;
You can't dereference, increment or decrement that pointer, because you don't know what type you point to. The idea is that void* can be used for functions like memcpy that just copy memory blocks around, and don't care about the type that they copy.
It's just a generic pointer, used to pass data when you don't know the type. You have to cast it to the correct type in order to use it.
It's a raw pointer to a spot in memory. It doesn't allow any pointer arithmetic like char * or int *.
Here's some examples of usage
http://theory.uwinnipeg.ca/programming/node87.html
It's a pointer to anything -- just a chunk of memory that you can play with -- might be an object, might be a char. You have to cast to do anything useful with it.
Building off my prior posting...
ATTENTION: All memory addresses here are fictional. I'm just making them up to illustrate a point.
Given:
int data[] = {10,11,12};
We now have:
0xffff0000-0xffff0003 with a value of (int)(10)
0xffff0004-0xffff0007 with a value of (int)(11)
0xffff0008-0xffff000b with a value of (int)(12)
(I'm not going to get into big-endian vs little-endian byte ordering here.)
If we have:
int * p = data;
We now have another memory location somewhere else, say:
0xaaaa0000-0xaaaa0003 with a value of (int*)0xffff0000
We can use p[1] [or *(p + 1)] to refer to *(int*)(0xffff0004) [=11] as sizeof(int)=4 and 0xffff0000+sizeof(int) = 0xffff0004.
If we have:
void * v = data;
We now have another memory location somewhere else, say:
0xbbbb0000-0xbbbb0003 with a value of (void*)0xffff0000.
However, void doesn't have any associated sizeof() information. We can't increment or decrement the pointer. We can't dereference to access the data stored in 0xffff0000. We can only utilize the value as a raw memory address.
If we want to use the data stored in (void*)0xffff0000, we first need to cast it to an appropriate type.
That said, (void *) is still quite useful as a means of passing addresses to arbitrary data structures around. For instance, memset(). It doesn't matter whether I'm zero'ing out a struct tm or a struct sockaddr. We just need a pointer to the struct and its size.
(This should go without saying, but... Beware using memset to zero out a class instance and, in doing so, overwriting the virtual pointer table.)
A void pointer cannot point to a class member in C++.
Related
I want to pass a pointer to a function.
Lets say I am creating a structure and declare a pointer to that structure. I allocate memory to that pointer and then I want to "pass" that pointer to a function so I can do stuff to that block of memory. How I do that?
It is done the same way as passing a normal variable. You shouldn't think of a pointer any different than a variable, as a pointer is a variable (although a bit special).
Say you have an integer and a pointer to that integer:
int a = 0;
int * ptr = &a;
Note that ptr and a are both variables, and in this instance, we use the reference operator & to reference a by &a which gives the address of a -- this is a pointer to a.
Now say you have two functions:
void foo(int i){}
void bar(int * p){}
Now these two functions do the same thing (nothing), but one takes an int and one takes a pointer to an int, int *. If you called foo(a) and modified i, i would be modified in the function body, but have no effect on a. If you called bar(ptr) and modified the value pointed to by ptr by using the dereference operator * as something like *ptr = 1, it would modify the value pointed to by ptr, which in this case would be a.
In your case, passing a struct would be just the same. Say you have a structure
struct MyStruct { int b; };
And had two more functions
void structFoo(struct MyStruct m) {}
void structBar(struct MyStruct * mp) {}
You could work on the pointer in the same way as our above int and int * functions, although you would now also have to access the struct components by dereferencing the struct with (*mp).b, or the shorthand version mp->b.
For ease of use, you may also want to do something like
typedef struct MyStruct MyStruct;
Which will allow you to use MyStruct as the type name rather than requiring struct MyStruct as in the above functions, although you may want to avoid doing this until you fully understand what is happening and get through difficulties with pointers.
Hopefully that gives you some idea of what is going on, although the C++ tutorial on pointers gives a much more in-depth discussion than what I can provide.
It would be a good exercise to create some small programs and mess around with pointer and regular types while printing the results to help understand what is happening where. You should remember that to allocate a pointer, you're going to need to use either new or malloc(), otherwise you will have a SEGFAULT error. This is not an issue when referencing a variable declared as I have done with &a above as the memory is already allocated when a declaration such as int a is made. A declaration of a pointer allocates the memory for that pointer, but not the memory that it points to. This eventually leads into the difference between the stack and the heap, although I wouldn't think about that until you have a very thorough understanding of pointers.
Structure in c/cpp is like all the other types. You can use & and * as you do it for int.
I'm working on a C++ project and I need a little sanity check and help on it. I want to return a void* pointer to a memory location in an array (which I'll do by
void* pointer = (void*) (array+index);
). The array is of chars so the indexing/byte numbering works out pretty nicely.
However, I want to be able to change what memory this location points to later on (a different spot in the array) as a response to some conditions in the code. Is there a way to do this? I'm messing around with void** pointers and trying to return a reference to the spot in memory where I stored the pointer, so I can just change the memory where the pointer itself is stored and change what pointer is read. I'm having trouble on the syntax to do this, though, and I'm not entirely sure it's possible.
I'm working within fairly rigid constraints and I can't get around the fact that I have to return the void* pointer, otherwise I think there are probably some nicer ways around this problem.
Any help would be greatly appreciated!
You can simply reassign the pointer:
char array[1200];
void * p = array + 17;
// later:
p = array + 29;
(No need for the cast, since object pointers are implicitly convertible to void pointers.)
to point somewhere else just cast the pointer back to char*, do your pointer arithmetics and that's it.
char *ptr_tmp = (char*)pointer;
ptr_tmp += 100;
pointer = (void*)ptr_tmp;
this is what I understood your problem is?!
I have a problem with sizeof(). I have a pointer in a class that I have created before. And this pointer is initialized as
static Book* books;
so it does point nothing. I want to determine if the pointer does point any array or not. So first question is that what are the solutions to do that because I can change the address of this pointer during the runtime to point an array. I try to use sizeof(pointer) but it does not help me enough. The return is the number 4. I can evaluate in this way if it refers anything or not.
This is my class :
class Tool
{
private:
static Book* books;
public:
static char* pgetStringIntoArray(string);
static string* pgetStringFromArray(char*);
static void printCharArray(char*);
static bool* addBook(Book*);
static bool* isStored(Book*);
};
And this is the method having a problem :
bool* Tool::isStored(Book* book)
{
bool* stored = new bool(false);
if(Tool::books)
{
cout << "NULL" << endl;
} else {
return stored;
}
}
No, you can't use sizeof to determine if the pointer is pointing to something. sizeof a pointer will be always the same size in the same architecture.
You can do this:
Tool::Book* books = NULL;
And, if you want to check if it's pointing to a valid non-null value, just do:
if (Tool::books) {
// books is pointing to something
}
Whenever you allocate memory for your pointer (array), if the allocation succeeds, the pointer will no longer be null. Since you are using C++, consider using std::vector to hold arrays of dynamic dimensions instead of arrays (pointers).
Much like C, C++ is statically typed - the various type sizes as returned by the sizeof operator are determined at compile time and do not change.
The proper way to do what you are asking would be to initialize your pointer to NULL and check for that afterwards. NULL is guaranteed not to refer to any valid memory address, which makes it a good marker for a non-existent pointer target. Initializing your pointers is a good practice anyway - it saves you from potential issues from dereferencing uninitialized pointers, issues that at best will result in nasty memory errors.
And yes, explicitly initializing the rest of your variables is also a good idea...
EDIT:
One not-so-minor detail: static fields in C and C++ programs are stored in a special section (e.g. BSS) of the executable and are automatically initialized to zero as the program loads. Therefore, you do not need to explicitly initialize static pointers to NULL; that has already been done for you...
Your problem is more with understanding pointers than with sizeof.
sizeof is a compile-time operation. For a pointer it always return sizeof(void*) (which is 8 bytes on most 64 bits architectures). Except for VLAs, sizeof returns a compile time constant.
C don't know the used size of any pointed zone -think of the result of malloc as an example- (because you could do pointer arithmetic). You need to manage it by yourself if needed.
I'm bit new to C++ and try to work things with Qt and came across this confusing thing:
The concepts on various tutorials state something like:
Class *obj;
*obj - will display the value of object stored at the referenced memory
obj - will be address of memory to which it is pointing
so, I would do something like
*obj=new Class();
but if I want to access a function, I have to do obj->function1();
instead of *obj->function1();
-- not sure why, since with normal objects [ normalObj.function1();] would work, since that's the value directly.
So, for pointer objects why do we use memory reference to access the function,
or is it that in case of normal objects also, its always references
P.S: Can someone guide me to a good tutorial of usage of pointers in C++, so that my queries like these can be directly addressed in it.
The * symbol is used to define a pointer and to dereference a pointer. For example, if I wanted to create a pointer to an int, I could do:
int *ptr;
In this example, the * is being used to declare that this is a pointer to an int. Now, when you are not declaring a pointer and you use the * symbol with an already declared pointer, then you are dereferencing it. As you probably know, a pointer is simply an address. When you dereference a pointer, you are obtaining the value that is being pointed to by that address. For example:
int pointToMe = 5;
int *ptr = &pointToMe;
std::cout << *ptr;
This will print out 5. Also, if you are assigning a pointer to a new address and it's not in the declaration, you do not use the * symbol. So:
int pointToMe = 5;
int *ptr;
ptr = &pointToMe;
is how you would do it. You can also deference the pointer to assign a new value to the value being pointed to by the address. Such as:
int pointToMe = 5;
int *ptr = &pointToMe;
std::cout << *ptr; // Prints out 5
*ptr = 27;
std::cout << *ptr; // Prints out 27
Now, -> acts like the deference symbol. It will dereference the pointer and then use the member functions and variables as if you had used . with a non-pointer object. Even with an object that is not a pointer you can use the -> by first getting the address:
CObj object;
(&object)->MemberFunction();
That's just a brief overview of pointers, hope it helps.
You can use the "normal" . to access the objects members, but you have to dereference the pointer first.
Due to operator precedence, this will look like (*obj).member. For those who think this is too much to write, obj->member is a shorter alternative.
If you have an object c of type Class, *c.ptr means dereferencing a pointer ptr that is a member of Class. That is one reason for (*obj).member, which means something else.
Actually, you're wrong. You do:
obj=new Class();
or
Class *obj = new Class;
which are completely different.
Class *obj;
*obj = new Class;
wouldn't compile.
obj is of type Class*, so that's what you can assign to it (and what new Class returns).
More precisely u can do like this
Class obj;
Class* obj_ptr;
obj_ptr = &obj;
// Now onwards you can use the pointer to access data members and function
obj_ptr->a = 10; // Like this
I looking for a clarification regarding the pointers. I have compiled the following code in bordland c++ 5.5.1 without any errors. But while i am trying to execute gives a core error.
int main ()
{
int x=10,y=20;
int &a=x;
int &b=y;
int *c;
int *d;
*c=x;
*d=y;
return 0;
}
Basically I am trying to create two reference variable (a,b) and assigned with two variables (x,y). after that I created two pointer variable(c,d) and tried to assign same variables (x,y). This gives me error while exection and not at compilation.
whether I am doing any wrong, this is not a standard assignments of pointer variable. why the pointer assignment is getting failed at this point. Please help me to understand this.
1st Update:
Thanks to all. First, I understood that I am working on a C++ feature (reference variable).
Second, I need to allocate memory for the pointer variables before play with it.
The code you posted is C++, not C. And your problem is that you need to make those pointers actually point at something:
int * c = & x; // make c point at x
* c = 42; // changes x
You have declared c and d as int pointers and you are trying to update their pointed values, they aren't pointing to anywhere valid since you never initialize them with valid memory.
Try c = &x; and then play with c.
You are dereferencing an invalid pointer. 'c' and 'd' were not assigned a memory location and so will be using whatever was previously in memory as their location. You need to do:
int *c = new int;
int *d = new int;
It looks to me like you're not entirely clear on the syntax.
Typing int *c is tricky, because it looks like you're declaring an integer with the name *c. However, this is not the case. This will declare a pointer to an integer, and in C/C++, pointers to a certain type are denoted by appending a * after the type name. Thus, you're declaring a variable of type int* (pointer to an integer), with the name c, even though the spacing makes it look different. For the record, typing int* c yields the same result, and is arguably more readable.
It follows then that typing *c does not reference your variable, as it is actually called c. Instead, what this does is dereference the pointer: it returns whatever object the pointer is pointing to. Or, if the pointer is invalid, cause an error.
If you want to declare a pointer and set it to point to an object at a later point, you need to do this:
int *c;
// stuff goes here
c = &x;
&x will return x's address in memory, which can be assigned to a pointer as a value. Then, you can manipulate the value through the pointer by dereferencing it: e.g. *c = 15.
You have defined two pointer variables c and d but you have not allocated any memory for them. You need to assign some memory to both of them.
Do this:
int *c = &x;
int *d = &y;