Q: Pointers (C++)


#1

Hey Guys,
Just starting to learn C++, and have come to the point where I am learning pointers. They seem so simple yet so complicated. Does anyone have any good advice on techniques for learning how to use pointers. Everything in C++ was going great until I hit the pointers section. So any advice would be greatly appreciated.

-Josh-


#2

Pointers are a hard-core, point-of-no-return, necessity in coding. A pointer is a variable that stores a memory location. This memory ‘pointer’ can then be assigned to a chunk of memory that you create so that you can use it later. so…

int * int_pointer;

creates a pointer that can hold the address of memory chunks of size ‘int’.

int_pointer = new int;

this creates an available memory chunk of size ‘int’ and assigns its location to int_pointer. As a result.

cout << int_pointer;

this will output the memory address of the chunk you just assigned to it with the ‘new int’.

How is this helpful?

*(int_pointer) = 10; 

This tells C++ that, instead of checking int_pointer directly, use the value stored at int_pointer to find the value stored at that memory address. This statement assigns it 10.

 cout << *(int_pointer);

Now, this statement will print out 10.

delete int_pointer;

One thing to remember about pointers, once you assign chunks of memory to them, to have to remember to delete those chunks later in the program when you’re done with them. C++ does not do this automatically.

This should be a good start. Reply if you have further questions.


#3

Hi Mummey,

Thanks for the reply. That definately helps, but one thing that really gets confusing is when using pointers for functions or a pointer to a pointer such as:

class person
{
private:

… //

public:

… //
};

void bsort(person**, int);
person* persPtr[100];

The understanding I get is that this makes almost a pointer nested inside of a pointer. But its use if very confusing. Once again any help on this would be very much appreciated.

-Josh-


#4

A pointer to a pointer can sometimes mean you have an array of pointers. In your example above you wrote:

person* persPtr[100];

That’s an array of 100 elements, each element being a person*. Pointers are the size of a native Integer data type (4 bytes on 32-bit systems, 8 bytes on 64-bit systems). So an array of pointers with 100 elements would only be 400 bytes of memory. But the objects that each pointer points to can be whatever size.

Why do we do this? Suppose your function has an argument that takes an array of similar objects. For instance that array of 100 “person” class objects. If you pass the entire 100 element array to the function, you might blow your stack. The stack is the temporary memory space for each function, this is where local variables and data passed as function arguments are stored. It’s a limited amount of memory so you don’t want to put too much in it. Like I said, pointers are only 4 bytes (on 32-bit systems) so you can easily fit a bunch of pointers onto the stack. Better still, pass only one pointer: a pointer to the array of pointers. That way you won’t run the risk of blowing your stack, and your functions can address large amounts of data at a time.

This “large” amount of data is actually located on the heap. Whenever you allocate data using malloc() or someother memory allocation routine, or even C++ “new” operator, that data is stored on the heap space. This is more persistent data storage. After a function returns, the stack is popped and local variables are cleared. But if you created data on the heap, it’ll still be there after a function returns. And by using pointers, you still know where that data is even after a function or member function returns.


#5

Thanks Vertizor, its starting to make more sense. So being that you have a pointer to the array of pointers you can point to a specific element of the array without transferring the entire array ot the function. Just point to the object which can then point to any of the individual elements of the array.

-Josh-


#6

What other programming experience do you have? Have you programmed in Java or other languages, or are you learning on C++?

One thing that helped me understand how pointers work is a class I took in assembly.

Once you get to the level of assembly, it’s easy to see that everything on a computer is just bits - for example, when a program is compiled you’ve just got the data block and the code block. When you execute, you’ve typically got a stack and a heap. But it’s all just bits in a big block of memory.

One of the best things I got out of the class was the ability to translate C to assembly, and then to machine language. Then you can think of C++ just passing each C function a pointer to the struct to operate on implicitly - the this pointer.

Probably not the answer you’re looking for, but it you’re looking to become a programmer long-term, understanding how your high-level language actually gets run will help your efficiency and ability to fix nasty bugs.


#7

Hi Nurcc,

I am pretty much learning in C++, and from the sounds of it, learning assembly code would be quite helpful. Especially in terms of optimizing code for speed performance. I think I need to start out developing plugins and then begin learning assembly code. Thanks for the reply.

-Josh-


#8

Just want to give you a friendly piece of advice. I can’t help that it’s going to come out sounding like a put-down so I want to make it clear that I’m just advising you, not putting you down. Please take this as just advice from someone who has been through this.

Almost every piece of writing that you may come across about assembly language (tutorial, book, etc.) they will say pretty much the same thing: don’t get into Assembly thinking you’ll make faster code.

Using assembly does not gaurentee faster code. In fact, if you are new and don’t fully know what you’re doing you’ll end up writing bad assembly code that may run slower, be more buggy and prone to error, and in all cases: harder to debug and find errors.

Here’s my story:
I was just playing around with some beginner algorithms for writing a ray tracer. Was able to draw a few squares and circles on the screen, cool. Then I heard about SSE, SSE2, 3DNow! processor extensions. Normally compilers won’t know how/when to properly use them (mine didn’t, MS VC++ 6.0) There are some specialized compilers that will make use of those SIMD extensions but it’s not always great, the trick is to organize your data in such a way that they can be streamed (in other words fed) to the CPU and the SIMD instructions executed upon them for optimal performance.

So I tweaked my rountine by replacing them with assembly code, in this scenario I was able to use assembly instructions my C/C++ compiler did not know about (the SSE, SSE2 instructions). The result? Turns out my assembly code took longer than the regular “unoptimized” code the compiler generated. Why? Switching between the FPU and the ALU (in other words floating point math processor to integer math processor) causes a brief stall. It’s nano seconds, you wouldn’t notice it. But… in a loop that runs 1000 times, the delay adds up and becomes a performance bottleneck.*

I will agree that learning assembly does open up your eyes to how much goes on in the background and what your programs are doing. But it is forcing you to work at the hardware level, and you pretty much have to think like a machine. Don’t attempt this until you’ve grasped C/C++. Just take it as a learning experience, using assembly language isn’t always practical. You have more to gain in terms of improving performance of your programs simply by improving the algorithm and high level code. People spend years developing quality C/C++ compilers, you’re going to have a very hard time competing with that not to mention the compiling power of your computer.

I don’t mean to just discourage you from learning, assembly is very interesting and can be fun. But you’ll be spending much more time learning assembly as oppose to any other language (spoken or programmatic). That time is better spent actually utilizing what you’ve learned in C/C++. Or depending on what you’re doing, multi-threaded programming is even more valuable and can be done easier in C/C++.

In case you’re wondering, why did my assembly code run slower than the compiler code? Even when I used SIMD instructions (SSE, SSE2) that was suppose to boost performance? Here’s what my code sort of looked like:

for( int i = 0; i < numVertices; i++)
{
   // I inlined assembly instructions here
}

Remember what I said: switching between floating point math and integer math causes a speed penalty, not to mention the penalty in branching code. My FOR loop was based on an integer (i), the code in the body of that loop operated on floating point data. Moreover it was using the SIMD registers and execution units (some of which are just remapped to the FPU registers). The speed penalties added up and made this code slower. My compiler probably would have seen that problem coming and converted the i variable into a float in order to bypass one speed penalty. Even when I changed my C code to make i a float, the improvement was very negligible. Not worth the many hours I spent on it.


#9

Vert’s completely right about this; don’t plan to use assembly to speed up your code.

Your priorities should be:
Writing clean (i.e. readable) code
Writing extensible code
Writing fast code

If it’s clean, odds are it’s also less buggy than if it’s not.
If it’s extensible, it’s easier to supplement, reuse, and optimize.
If you don’t do the first two, the latter will take you an eternity.

And get into the habit of documenting your code, and doing some design work before you write it, even if it’s not a formal design document. It doesn’t even have to be UML, or even a visual diagram (though I find that easier to work with), but think about what you would have to write down in order for someone else to implement your design, and use that as a reference for what to include. You’d be surprised at how much better that alone will make your code.


#10

Reading this stuff helped clear things up for ME, and I’ve been coding in C++ exclusively for over 3 years. Then again, I never WAS that great a programmer. :wink:

But seriously, the importance of documenting your code can’t be stressed enough. You have to write it as if you were explaining it to someone who has no idea what your code does. Someone like YOU 3 months after you write it. Hell if I had properly documented my project, I might have finished my Master’s…


#11

I hear you :slight_smile: It’s always a pleasure when a client project you wrote (and did not document) comes back to haunt you after several months -> fun fun fun :surprised

I use a very simple method to ensure that my code is ocumented/commented: When writing a function I simply write down the things (phase by phase) that the function is supposed to do then write the code.

Like:
// Init stuff

// Create n samples

// Get 2 random numbers - x & y

// Map them to -1 to 1 interval

// Check if they are on an unit disk

// If so compute z and store

// Update sample counter

=>

 	// Init stuff 
	float x, y;
 
  // Create n samples
 for(i = 0; i < MAX_SAMPLES; )
 {
		// Get 2 random numbers - x & y
		x = Rand();
		y = Rand();
 
		// Map them to -1 to 1 interval
		x = 2 * x - 1;
		y = 2 * y - 1;
 
		// Check if they are on an unit disk
		if(x * x + y * y < 1)
		{
			// If so compute z and store
			zs[i] = sqrt(1.0 - x * x - y * y);
			xs[i] = x;
			ys[i] = y;
 
			// Update sample counter
			++i;
		}
 }


pipari


#12

I seriously hope to never run across some code from you … [re: commenting is not about having commented, good code needs no comment and unnecessary (bs) comments make life even harder] …cheers :deal:


#13

Words like that will end your job tenure pretty quickly in some places. “Good code needs no comment” is one of the oldest, and DUMBEST, myths in programming.

Don’t believe me? Try to write a program 1,000 lines long. Let me sit for a week without looking at it. Now open it back up and see if you can still remember what it does.

Consider this: 1000 lines is enough for one script. A more realistic program will have over 50,000 lines easily! Still think you can write it without comments!?!


#14

Trust me, you won’t :stuck_out_tongue: Funny thing is that every guy (& subcontractor) I have worked with have said exactly the opposite :shrug: Granted, the example I posted was pretty simplistic.

Consider this: 1000 lines is enough for one script. A more realistic program will have over 50,000 lines easily! Still think you can write it without comments!?!

Better yet, try to fix some real world program that consists 50,000+ lines of uncommented code written by some other guy (who no longer works for the company) -> fun fun :surprised

Peace :thumbsup:


pipari


#15

I agree, everybody should respect the 3 golden rules:

  1. commenting code is for wussies
  2. name variables and functions randomly with disregard for common standards
  3. be creative, scalability and portability issues can always be resolved at the last minute anyway

#16

I tend to block everything out with comments just as a reminder to me to start with. I then loose any really basic ones like:

/* for loop goes here */

They are very useful reminders to begin with though. Even if it seems simple it’s always godo to have a template to start from.

Then make sure you keep then ones important to solving the problem like:

/* this is the format we are reading NAME STATE LOCATION /
/
build tree of closest points */

and the most important ones which will bite you later:

/* we are doing this because the compiler is broken… in a perfect world we’d really do this… */

I have to admit I should document far more than I do, but most of my stuff is in a constant state of flux (ie specific solutions for a particular shot) rather than one big project, keeping this stuff up to date is a nightmare. (even the code to a certain degree!)

Simon


#17

Another benefit is that writing comments indicating what you plan to do makes you think about it before you commit it to code.

And if you’re just starting out, you really should take the time to learn process. And when you interview, ask about process. If they don’t have a process, then either it’s a sweatshop, or they don’t do anything that isn’t trivial to implement.


#18

I agree, everybody should respect the 3 golden rules:

  1. commenting code is for wussies
  2. name variables and functions randomly with disregard for common standards
  3. be creative, scalability and portability issues can always be resolved at the last minute anyway

The best guide I’ve seen is How to Write Unmaintainable Code

Another good resource is The Daily WTF, which has current, real-world examples. I’m sure most programmers who have worked in the real world have had to maintain ugly code (either their own, or others’). And most programmers have written their fair share, while learning. I still remember learning basic, and all the examples used single-letter variable names - it was a huge breakthrough when I found out you could use multi-letter variable names, and therefore have more than 26 variables… :slight_smile:


#19

I’ve got no probs with comments… but obviously there was some fatal misunderstanding here

most of those comments are just plain bs… sorry but it’s like that… like ‘init stuff’ and ‘update sample counter’ as the most blatant ones … no probs with eg ‘map them to -1 to 1 interval’ …

and mummey as an example … the for loop in ‘create n samples’ is perfectly good code so it has no need for a comment …

…unnecessary (bs) comments make life even harder…

so please try to look at the reply seriously and not as a hopeful chance to do some nice flamebait hopping… no harm intended … but it looks like anything thats not totally ‘new ones’ friendly gets dissed down in no time …so see you next time in the ‘help! beginner w/o access to google’-thread…or …errr…not

cheers :beer:


#20

Misunderstanding, yes. You missed the point I was trying to make. I tried to demonstrate a process that ensures that the code gets commented: 1) Write down the phases of the algorithm / function etc. as comments 2) then write the code. As I said it was just a simple example (a first piece of my non-work related code I could find) and many of those comments are unnecessary or bs as you so politely pointed out.

I have used this method for about six years now to ensure that my work related code gets commented. And as I said this method has proved to be quite good and the feedback I have gotten from my collegues and subcontractors has always been positive. Even the noobs understand what the code does -> they don’t bother me with their questions :stuck_out_tongue:

And yes, unnecessary comments can make your life harder but uncommented code can make your life even harder: I currently have in front of me about 60,000 lines of uncommented code (a process management tool) written by some other guy. I would prefer overcommented code over this any day :wink:

Peace :slight_smile:


pipari