![]() |
|
#1
|
|||
|
|||
Need help with pointer to pointerHello Folks,
I have been out of touch with C for a while now. Forgettin some basics. Following code is a simulator of the part of the large code that I am planning to implement. Basically here what it is, i have array of pointer stored in a structure. I do not know as to how many pointers I will hold this array in the begining. As the code progress I go on adding pointer to the array. I keep a count of how many pointers I added to the array in the structure itself by incrementing it everytime I add a pointer to the array. Now this is what I am doing (or atleast tryin) in the following code. It's working, but I am not sure if what I am seeing is correct. Can some one help me understand it. CPP / C++ / C Code:
Following is the sample output. My question is why the values of (*p)'' are different than what we are seeing in (*p) and (*p)'. Quote:
BTW, this is anintel PC running Linux and my compiler is gcc. Thanks, |
|
#2
|
|||
|
|||
Re: Need help with pointer to pointerQuote:
You have assigned the address of the array elements to values of (*p) (after you printed out the values that malloc() gave you). Put this before the while() loop: CPP / C++ / C Code:
These are what you see at the end. Now, that that's out of the way, I have to say that everything that I can think of that could be wrong with this program is wrong. (And I mean really wrong.) You have a loop that calls malloc() for sizeof(int *) and sizeof (int). Now it just turns out (according to your printout) that each time through the loop the address of the next thing that malloc() gives you is 32 bytes greater that the previous time through the loop. Please note that this is just "happenstance", and is not in any way defined by the language standard. Why 32 bytes? It's implementation-dependent. You save the very first address in a variable, top, that is an (int **), and later in the program you start at that address and increment it by (sizeof(int **) +sizeof(int *). Now if the size of a pointer is 4 bytes and you add one to it, then you have actually added four to its value. If you increment a pointer by 4 + 4 you are actually adding 32 to the byte count. So, in this particular case you end up pointing to the next thing that was allocated. This is really horrible, and I can't tell you how sorry I am that it "just happened" to appear to be giving you something familiar in your printout. It is wrong, wrong, wrong. (And I mean really wrong.) 1. There is absolutely no guarantee that successive calls to malloc() will give any kind of sequential addresses. 2. It just happens that in this case malloc() gives blocks of 16 bytes for each call with sizeof(int *) and sizeof(int). (So each time through the loop gets a value that is 32 bytes more than the previous time through the loop.) Note that on some systems (64-bit Linux with gcc, for example), sizeof(int *) is 8 and sizeof (int) is 4. I have no idea (and have absolutely no interest in finding out) what the actual boundaries of successive blocks from malloc() happen to fall on. It doesn't really matter, since it is undefined behavior. Anything that depends on sizeof(int *) and sizeof(int) being somehow related is doomed, doomed, doomed. 3. When you get something from malloc(), you are allowed to access the specific area defined by the argument you gave to malloc(), and other stuff is strictly off-limits. 4. I am just too tired to go on.... In C, if you want to have an array (of anything) but you don't know how big it is eventually going to be, then you might think of doing something else (maybe a linked list or some such thing). On the other hand, there are plenty of applications that really need it to be an array (where an array is defined to be something that occupies a contiguous memory). The function malloc() for any given call, will give you a block of contiguous memory, and that's why it's so useful for making dynamic arrays. However, and I hate to repeat myself, but: successive calls to malloc() will not necessarily give you contiguous memory blocks. In C one way to do it is to use malloc() to get a specific size block of memory for your array. If your needs grow beyond the original block, then you can use realloc() to make the array grow. This is the kind of thing that is taken care automatically by certain C++ classes (like strings and vectors, and stuff like that). Regards, Dave |
|
#3
|
|||
|
|||
Re: Need help with pointer to pointerHi Dave,
thanks for you response. How about this.? I think this is what I was intending to do. Code:
I see some problem with the printf() output, 4th element I add to the array is not displayed correcty. Pointer offsets by one byte memory location. Is this a printf() related problem? sample Output Quote:
Thanks for your help |
|
#4
|
|||
|
|||
Re: Need help with pointer to pointerHi Dave,
Never mind. Changing the following statement, CPP / C++ / C Code:
to CPP / C++ / C Code:
fixed the problem. Quote:
|
|
#5
|
|||
|
|||
Re: Need help with pointer to pointerQuote:
OK! That's the idea. Now, if you are going to get serious about this, there are a couple of points that you might consider: First, using realloc for each and every new item is very inefficient. I think the usual thing is to allocate a sizeable chunk of memory and when its limit is reached, then realloc to get some more. Then, I think you should always test the return values of malloc() and realloc(), since it is possible that memory is exhausted or, maybe, fragmented in such a way that no further allocation is possible. After all, the only way that you could justify the complexity of using realloc is for programs whose data requirements could be very large (otherwise just used fixed arrays, right?). Now with large, sophisticated programs, if realloc fails, the program might take some corrective action by writing some of its data base onto a disk file and freeing its memory, then, maybe reading it back in as needed into some contiguous memory. The point is that if realloc fails, then the way you have written it, all is lost, since you wipe out the previous value of the pointer. I would suggest something like the following: CPP / C++ / C Code:
Of course if all you are going to do is exit(), then there is value in worrying about saving the value of the pointer, since all is lost. However if you do something like my example above, you may be able to figure out some way to continue, since the original value of p is intact. Let us know how it goes. Regards, Dave |
|
#6
|
|||
|
|||
Re: Need help with pointer to pointerThanks Dave, i will your inputs in mind while coding.
Thanks again for your help. Regards, |
Recent GIDBlog
Meeting the populace by crystalattice
| Thread Tools | Search this Thread |
| Rate This Thread | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| 2D arrays:dynamic allocation and freeing | bravetanveer | C Programming Language | 48 | 27-Nov-2007 15:55 |
| Pointer Usage in C++: Beginner to Advanced | varunhome | C++ Forum | 0 | 19-Aug-2005 09:25 |
| [Tutorial] Pointers in C (Part II) | Stack Overflow | C Programming Language | 0 | 27-Apr-2005 17:36 |
| [Tutorial] Pointers in C (Part I) | Stack Overflow | C Programming Language | 1 | 08-Apr-2005 18:35 |
Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The