Hi I am a graduate student studying scientific computing using c++. Some of our research focus on speed of an algorithm, therefore it is important to construct array structure that is fast enough.
I've seen two ways of constructing 3D Arrays.
First one is to use vector liblary.
vector<vector<vector<double>>> a (isize,vector<double>(jsize,vector<double>(ksize,0)))
This gives 3D array structure of size isize x jsize x ksize.
The other one is to construct a structure containing 1d array of size isize* jsize * ksize using
new double[isize*jsize*ksize]. To access the specific location of (i,j,k) easily, operator overloading is necessary(am I right?).
And from what I have experienced, first one is much faster since it can access to location (i,j,k) easily while latter one has to compute location and return the value. But I have seen some people preferring latter one over the first one. Why do they prefer the latter setting? and is there any disadvantage of using the first one?
Thanks in adavance.
Main difference between those will be the layout:
vector<vector<vector<T>>>
This will get you a 1D array of vector<vector<T>>.
Each item will be a 1D array of vector<T>.
And each item of those 1D array will be a 1D array of T.
The point is, vector itself does not store its content. It manages a chunk of memory, and stores the content there. This has a number of bad consequences:
For a matrix of dimension X·Y·Z, you will end up allocating 1 + X + X·Y memory chunks. That's horribly slow, and will trash the heap. Imagine: a cube matrix of size 20 would trigger 421 calls to new!
To access a cell, you have 3 levels of indirection:
You must access the vector<vector<vector<T>>> object to get pointer to top-level memory chunk.
You must then access the vector<vector<T>> object to get pointer to second-level memory chunk.
You must then access the vector<T> object to get pointer to the leaf memory chunk.
Only then you can access the T data.
Those memory chunks will be spread around the heap, causing a lot of cache misses and slowing the overall computation.
Should you get it wrong at some point, it is possible to end up with some lines in your matrix having different lengths. After all, they're independent 1-d arrays.
Having a contiguous memory block (like new T[X * Y * Z]) on the other hand gives:
You allocate 1 memory chunk. No heap trashing, O(1).
You only need to access the pointer to the memory chunk, then can go straight for desired element.
All matrix is contiguous in memory, which is cache-friendly.
Those days, a single cache miss means dozens or hundreds lost computing cycles, do not underestimate the cache-friendliness aspect.
By the way, there is a probably better way you didn't mention: using one of the numerous matrix libraries that will handle this for you automatically and provide nice support tools (like SSE-accelerated matrix operations). One such library is Eigen, but there are plenty others.
→ You want to do scientific computing? Let a lib handle the boilerplate and the basics so you can focus on the scientific computing part.
In my point of view, there are too much advantages std::vector's have over normal plain arrays.
In short here are some:
It is much harder to create memory leaks with std::vector. This point alone is one of the biggest advantages. This has nothing to do with performance, but should be considered all the time.
std::vector is part of the STL. This part of C++ is one of the most used one. Thousands of people use the STL and so they get "tested" every day. Over the last years they got optimized so radically, they don't lack any performance anymore. (pls correct me if i see this wrong)
Handling with std::vector is easy as 1, 2, 3. No pointer handling no nothing... Just accessing it via methods or with []-operator and more other methods.
First of all, the idea that you access (i,j,k) in your vec^3 directly is somewhat flawed. What you have is a structure of pointers where you need to dereference three pointers along the way. Note that I have no idea whether that is faster or slower than computing the position within a one-dimensional array, though. You'd need to test that and it might depend on the size of your data (especially whether it fits in a chunk).
Second, the vector^3 requires pointers and vector sizes, which require more memory. In many cases, this will be irrelevant (as the image grows cubically but the memory difference only quadratically) but if your algoritm is really going to fill out any memory available, that can matter.
Third, the raw array stores everything in consecutive memory, which is good for streaming and can be good for certain algorithms because of quick cache accesses. For example when you add one 3D image to another.
Note that all of this is about hyper-optimization that you might not need. The advantages of vectors that skratchi.at pointed out in his answer are quite strong, and I add the advantage that vectors usually increase readability. If you do not have very good reasons not to use vectors, then use them.
If you should decide for the raw array, in any case, make sure that you wrap it well and keep the class small and simple, in order to counter problems regarding leaks and such.
Welcome to SO.
If everything what you have are the two alternatives, then the first one could be better.
Prefer using STL array or vector instead of a C array
You should avoid to use C++ plain arrays since you need to manage yourself the memory allocating/deallocating with new/delete and other boilerplate code like keep track of the size/check bounds. In clearly words "C arrays are less safe, and have no advantages over array and vector."
However, there are some important drawbacks in the first alternative. Something I would like to highlight is that:
std::vector<std::vector<std::vector<T>>>
is not a 3-d matrix. In a matrix, all the rows must have the same size. On the other hand, in a "vector of vectors" there is no guarantee that all the nested vectors have the same length. The reason is that a vector is a linear 1-D structure as pointed out in the #spectras answer. Hence, to avoid all sort of bad or unexpected behaviours, you must to include guards in your code to obtain the rectangular invariant guaranteed.
Luckily, the first alternative is not the only one you may have in hands.
For example, you can replace the c-style array by a std::array:
const int n = i_size * j_size * k_size;
std::array<int, n> myFlattenMatrix;
or use std::vector in case your matrix dimensions can change.
Accessing element by its 3 coordinates
Regarding your question
To access the specific location of (i,j,k) easily, operator
overloading is necessary(am I right?).
Not exactly. Since there isn't a 3-parameter operator for neither std::vector nor array, you can't overload it. But you can create a template class or function to wrap it for you. In any case you will must to deference the 3 vectors or calculate the flatten index of the element in the linear storage.
Considering do not use a third part matrix library like Eigen for your experiments
You aren't coding it for production but for research purposes instead. Particularly, your research is exactly regarding the performance of algorithms. In that case, I prefer do not recommend to use a third part library, like Eigen, absolutely. Of course it depends a lot of what kind of "speed of an algorithm" metrics are you willing to gather, but Eigen, for instance, will do a lot of things under the hood (like vectorization) which will have a tremendous influence on your experiments. Since it will be hard for you to control those unseen optimizations, these library's features may lead you to wrong conclusions about your algorithms.
Algorithm's performance and big-o notation
Usually, the performance of algorithms are analysed by using the big-O approach where factors like the actual time spent, hardware speed or programming language traits aren't taken in account. The book "Data Structures and Algorithms in C++" by Adam Drozdek can provide more details about it.
Well, after a full year of programming and only knowing of arrays, I was made aware of the existence of vectors (by some members of StackOverflow on a previous post of mine). I did a load of researching and studying them on my own and rewrote an entire application I had written with arrays and linked lists, with vectors. At this point, I'm not sure if I'll still use arrays, because vectors seem to be more flexible and efficient. With their ability to grow and shrink in size automatically, I don't know if I'll be using arrays as much. At this point, the only advantage I personally see is that arrays are much easier to write and understand. The learning curve for arrays is nothing, where there is a small learning curve for vectors. Anyway, I'm sure there's probably a good reason for using arrays in some situation and vectors in others, I was just curious what the community thinks. I'm an entirely a novice, so I assume that I'm just not well-informed enough on the strict usages of either.
And in case anyone is even remotely curious, this is the application I'm practicing using vectors with. Its really rough and needs a lot of work: https://github.com/JosephTLyons/Joseph-Lyons-Contact-Book-Application
A std::vector manages a dynamic array. If your program need an array that changes its size dynamically at run-time then you would end up writing code to do all the things a std::vector does but probably much less efficiently.
What the std::vector does is wrap all that code up in a single class so that you don't need to keep writing the same code to do the same stuff over and over.
Accessing the data in a std::vector is no less efficient than accessing the data in a dynamic array because the std::vector functions are all trivial inline functions that the compiler optimizes away.
If, however, you need a fixed size then you can get slightly more efficient than a std::vector with a raw array. However you won't loose anything using a std::array in those cases.
The places I still use raw arrays are like when I need a temporary fixed-size buffer that isn't going to be passed around to other functions:
// some code
{ // new scope for temporary buffer
char buffer[1024]; // buffer
file.read(buffer, sizeof(buffer)); // use buffer
} // buffer is destroyed here
But I find it hard to justify ever using a raw dynamic array over a std::vector.
This is not a full answer, but one thing I can think of is, that the "ability to grow and shrink" is not such a good thing if you know what you want. For example: assume you want to save memory of 1000 objects, but the memory will be filled at a rate that will cause the vector to grow each time. The overhead you'll get from growing will be costly when you can simply define a fixed array
Generally speaking: if you will use an array over a vector - you will have more power at your hands, meaning no "background" function calls you don't actually need (resizing), no extra memory saved for things you don't use (size of vector...).
Additionally, using memory on the stack (array) is faster than heap (vector*) as shown here
*as shown here it's not entirely precise to say vectors reside on the heap, but they sure hold more memory on the heap than the array (that holds none on the heap)
One reason is that if you have a lot of really small structures, small fixed length arrays can be memory efficient.
compare
struct point
{
float coords[4]
}
with
struct point
{
std::vector<float> coords;
}
Alternatives include std::array for cases like this. Also std::vector implementations will over allocate, meaning that if you want resize to 4 slots, you might have memory allocated for 16 slots.
Furthermore, the memory locations will be scattered and hard to predict, killing performance - using an exceptionally larger number of std::vectors may also need to memory fragmentation issues, where new starts failing.
I think this question is best answered flipped around:
What advantages does std::vector have over raw arrays?
I think this list is more easily enumerable (not to say this list is comprehensive):
Automatic dynamic memory allocation
Proper stack, queue, and sort implementations attached
Integration with C++ 11 related syntactical features such as iterator
If you aren't using such features there's not any particular benefit to std::vector over a "raw array" (though, similarly, in most cases the downsides are negligible).
Despite me saying this, for typical user applications (i.e. running on windows/unix desktop platforms) std::vector or std::array is (probably) typically the preferred data structure because even if you don't need all these features everywhere, if you're already using std::vector anywhere else you may as well keep your data types consistent so your code is easier to maintain.
However, since at the core std::vector simply adds functionality on top of "raw arrays" I think it's important to understand how arrays work in order to be fully take advantage of std::vector or std::array (knowing when to use std::array being one example) so you can reduce the "carbon footprint" of std::vector.
Additionally, be aware that you are going to see raw arrays when working with
Embedded code
Kernel code
Signal processing code
Cache efficient matrix implementations
Code dealing with very large data sets
Any other code where performance really matters
The lesson shouldn't be to freak out and say "must std::vector all the things!" when you encounter this in the real world.
Also: THIS!!!!
One of the powerful features of C++ is that often you can write a class (or struct) that exactly models the memory layout required by a specific protocol, then aim a class-pointer at the memory you need to work with to conveniently interpret or assign values. For better or worse, many such protocols often embed small fixed sized arrays.
There's a decades-old hack for putting an array of 1 element (or even 0 if your compiler allows it as an extension) at the end of a struct/class, aiming a pointer to the struct type at some larger data area, and accessing array elements off the end of the struct based on prior knowledge of the memory availability and content (if reading before writing) - see What's the need of array with zero elements?
embedding arrays can localise memory access requirement, improving cache hits and therefore performance
I have a little problem here, i write c++ code to create an array but when i want to set array size to 100,000,000 or more i got an error.
this is my code:
int i=0;
double *a = new double[n*n];
this part is so important for my project.
When you think you need an array of 100,000,000 elements, what you actually need is a different data structure that you probably have never heard of before. Maybe a hash map, or maybe a sparse matrix.
If you tell us more about the actual problem you are trying to solve, we can provide better help.
In general, the only reason that would fail would be due to lack of memory/memory fragmentation/available address space. That is, trying to allocate 800MB of memory. Granted, I have no idea why your system's virtual memory can't handle that, but maybe you allocated a bunch of other stuff. It doesn't matter.
Your alternatives are to tricks like memory-mapped files, sparse arrays, and so forth instead of an explicit C-style array.
If you do not have sufficient memory, you may need to use a file to store your data and process it in smaller chunks.
Don't know if IMSL provides what you are looking for, however, if you want to work on smaller chunks you might devise an algorithm that can call IMSL functions with these small chunks and later merge the results. For example, you can do matrix multiplication by combining multiplication of sub-matrices.
I'm fresh out of college and have been working in C++ for some time now. I understand all the basics of C++ and use them, but I'm having a hard time grasping more advanced topics like pointers and classes. I've read some books and tutorials and I understand the examples in them, but then when I look at some advanced real life examples I cannot figure them out. This is killing me because I feel like its keeping me from bring my C++ programming to the next level. Did anybody else have this problem? If so, how did you break through it?
Does anyone know of any books or tutorials that really describe pointers and class concepts well?
or maybe some example code with good descriptive comments using advanced pointers and class techniques?
any help would be greatly appreciated.
Understanding Pointers in C/C++
Before one can understand how pointers work, it is necessary to understand how variables are stored and accessed in programs. Every variable has 2 parts to it - (1) the memory address where the data is stored and (2) the value of the data stored.
The memory address is often referred to as the lvalue of a variable, and the value of the data stored is referred to as the rvalue (l and r meaning left and right).
Consider the statement:
int x = 10;
Internally, the program associates a memory address with the variable x. In this case, let's assume that the program assigns x to reside at the address 1001 (not a realistic address, but chosen for simplicity). Therefore, the lvalue (memory address) of x is 1001, and the rvalue (data value) of x is 10.
The rvalue is accessed by simply using the variable “x”. In order to access the lvalue, the “address of” operator (‘&’) is needed. The expression ‘&x’ is read as "the address of x".
Expression Value
----------------------------------
x 10
&x 1001
The value stored in x can be changed at any time (e.g. x = 20), but the address of x (&x) can never be changed.
A pointer is simply a variable that can be used to modify another variable. It does this by having a memory address for its rvalue. That is, it points to another location in memory.
Creating a pointer to “x” is done as follows:
int* xptr = &x;
The “int*” tells the compiler that we are creating a pointer to an integer value. The “= &x” part tells the compiler that we are assigning the address of x to the rvalue of xptr. Thus, we are telling the compiler that xptr “points to” x.
Assuming that xptr is assigned to a memory address of 1002, then the program’s memory might look like this:
Variable lvalue rvalue
--------------------------------------------
x 1001 10
xptr 1002 1001
The next piece of the puzzle is the "indirection operator" (‘*’), which is used as follows:
int y = *xptr;
The indirection operator tells the program to interpret the rvalue of xptr as a memory address rather than a data value. That is, the program looks for the data value (10) stored at the address provided by xptr (1001).
Putting it all together:
Expression Value
--------------------------------------------
x 10
&x 1001
xptr 1001
&xptr 1002
*xptr 10
Now that the concepts have been explained, here is some code to demonstrate the power of pointers:
int x = 10;
int *xptr = &x;
printf("x = %d\n", x);
printf("&x = %d\n", &x);
printf("xptr = %d\n", xptr);
printf("*xptr = %d\n", *xptr);
*xptr = 20;
printf("x = %d\n", x);
printf("*xptr = %d\n", *xptr);
For output you would see (Note: the memory address will be different each time):
x = 10
&x = 3537176
xptr = 3537176
*xptr = 10
x = 20
*xptr = 20
Notice how assigning a value to ‘*xptr’ changed the value of ‘x’. This is because ‘*xptr’ and ‘x’ refer to the same location in memory, as evidenced by ‘&x’ and ‘xptr’ having the same value.
Pointers and classes aren't really advanced topics in C++. They are pretty fundamental.
For me, pointers solidified when I started drawing boxes with arrows. Draw a box for an int. And int* is now a separate box with an arrow pointing to the int box.
So:
int foo = 3; // integer
int* bar = &foo; // assigns the address of foo to my pointer bar
With my pointer's box (bar) I have the choice of either looking at the address inside the box. (Which is the memory address of foo). Or I can manipulate whatever I have an address to. That manipulation means I'm following that arrow to the integer (foo).
*bar = 5; // asterix means "dereference" (follow the arrow), foo is now 5
bar = 0; // I just changed the address that bar points to
Classes are another topic entirely. There's some books on object oriented design, but I don't know good ones for beginners of the top of my head. You might have luck with an intro Java book.
This link has a video describing how pointers work, with claymation. Informative, and easy to digest.
This page has some good information on the basic of classes.
I used to have a problem understand pointers in pascal way back :) Once i started doing assembler pointers was really the only way to access memory and it just hit me. It might sound like a far shot, but trying out assembler (which is always a good idea to try and understand what computers is really about) probably will teach you pointers. Classes - well i don't understand your problem - was your schooling pure structured programming? A class is just a logical way of looking at real life models - you're trying to solve a problem which could be summed up in a number of objects/classes.
Pointers and classes are completely different topics so I wouldn't really lump them in together like this. Of the two, I would say pointers are more fundamental.
A good exercise for learning about what pointers are is the following:
create a linked list
iterate through it from start to finish
reverse it so that the head is now the back and the back is now the head
Do it all on a whiteboard first. If you can do this easily, you should have no more problems understanding what pointers are.
Pointers already seem to be addressed (no pun intended) in other answers.
Classes are fundamental to OO. I had tremendous trouble wrenching my head into OO - like, ten years of failed attempts. The book that finally helped me was Craig Larman's "Applying UML and Patterns". I know it sounds as if it's about something different, but it really does a great job of easing you into the world of classes and objects.
We were just discussing some of the aspects of C++ and OO at lunch, someone (a great engineer actually) was saying that unless you have a really strong programming background before you learn C++, it will literally ruin you.
I highly recommend learning another language first, then shifting to C++ when you need it. It's not like there is anything great about pointers, they are simply a vestigial piece left over from when it was difficult for a compiler convert operations to assembly efficiently without them.
These days if a compiler can't optimize an array operation better then you can using pointers, your compiler is broken.
Please don't get me wrong, I'm not saying C++ is horrible or anything and don't want to start an advocacy discussion, I've used it and use it occasionally now, I'm just recommending you start with something else.
It's really NOT like learning to drive a manual car then easily being able to apply that to an automatic, it's more like learning to drive on one of those huge construction cranes then assuming that will apply when you start to drive a car--then you find yourself driving your car down the middle of the street at 5mph with your emergency lights on.
[edit] reviewing that last paragraph--I think that may have been my most accurate analogy ever!
To understand pointers, I can't recommend the K&R book highly enough.
The book that cracked pointers for me was Illustrating Ansi C by Donald Alcock. Its full of hand-drawn-style box and arrow diagrams that illustrate pointers, pointer arithmetic, arrays, string functions etc...
Obviously its a 'C' book but for core fundamentals its hard to beat
From lassevek's response to a similar question on SO:
Pointers is a concept that for many
can be confusing at first, in
particular when it comes to copying
pointer values around and still
referencing the same memory block.
I've found that the best analogy is to
consider the pointer as a piece of
paper with a house address on it, and
the memory block it references as the
actual house. All sorts of operations
can thus be easily explained:
Copy pointer value, just write the address on a new piece of paper
Linked lists, piece of paper at the house with the address of the next
house on it
Freeing the memory, demolish the house and erase the address
Memory leak, you lose the piece of paper and cannot find the house
Freeing the memory but keeping a (now invalid) reference, demolish the
house, erase one of the pieces of
paper but have another piece of paper
with the old address on it, when you
go to the address, you won't find a
house, but you might find something
that resembles the ruins of one
Buffer overrun, you move more stuff into the house than you can
possibly fit, spilling into the
neighbours house
For Pointers:
I found this post had very thoughtful discussion about pointers. Maybe that would help. Are you familar with refrences such as in C#? That is something that actually refers to something else? Thats probably a good start for understanding pointers.
Also, look at Kent Fredric's post below on another way to introduce yourself to pointers.
Learn assembly language and then learn C. Then you will know what the underlying principles of machine are (and thefore pointers).
Pointers and classes are fundamental aspects of C++. If you don't understand them then it means that you don't really understand C++.
Personally I held back on C++ for several years until I felt I had a firm grasp of C and what was happening under the hood in assembly language. Although this was quite a long time ago now I think it really benefited my career to understand how the computer works at a low-level.
Learning to program can take many years, but you should stick with it because it is a very rewarding career.
For pointers and classes, here is my analogy. I'll use a deck of cards. The deck of cards has a face value and a type (9 of hearts, 4 of spades, etc.). So in our C++ like programming language of "Deck of Cards" we'll say the following:
HeartCard card = 4; // 4 of hearts!
Now, you know where the 4 of hearts is because by golly, you're holding the deck, face up in your hand, and it's at the top! So in relation to the rest of the cards, we'll just say the 4 of hearts is at BEGINNING. So, if I asked you what card is at BEGINNING, you would say, "The 4 of hearts of course!". Well, you just "pointed" me to where the card is. In our "Deck of Cards" programming language, you could just as well say the following:
HeartCard card = 4; // 4 of hearts!
print &card // the address is BEGINNING!
Now, turn your deck of cards over. The back side is now BEGINNING and you don't know what the card is. But, let's say you can make it whatever you want because you're full of magic. Let's do this in our "Deck of Cards" langauge!
HeartCard *pointerToCard = MakeMyCard( "10 of hearts" );
print pointerToCard // the value of this is BEGINNING!
print *pointerToCard // this will be 10 of hearts!
Well, MakeMyCard( "10 of hearts" ) was you doing your magic and knowing that you wanted to point to BEGINNING, making the card a 10 of hearts! You turn your card over and, voila! Now, the * may throw you off. If so, check this out:
HeartCard *pointerToCard = MakeMyCard( "10 of hearts" );
HeartCard card = 4; // 4 of hearts!
print *pointerToCard; // prints 10 of hearts
print pointerToCard; // prints BEGINNING
print card; // prints 4 of hearts
print &card; // prints END - the 4 of hearts used to be on top but we flipped over the deck!
As for classes, we've been using classes in the example by defining a type as HeartCard. We know what a HeartCard is... It's a card with a value and the type of heart! So, we've classified that as a HeartCard. Each language has a similar way of defining or "classifying" what you want, but they all share the same concept! Hope this helped...
In the case of classes I had three techniques that really helped me make the jump into real object oriented programming.
The first was I worked on a game project that made heavy use of classes and objects, with heavy use of generalization (kind-of or is-a relationship, ex. student is a kind of person) and composition (has-a relationship, ex. student has a student loan). Breaking apart this code took a lot of work, but really brought things into perspective.
The second thing that helped was in my System Analysis class, where I had to make http://www.agilemodeling.com/artifacts/classDiagram.htm">UML class diagrams. These I just really found helped me understand the structure of classes in a program.
Lastly, I help tutor students at my college in programming. All I can really say about this is you learn a lot by teaching and by seeing other people's approach to a problem. Many times a student will try things that I would never have thought of, but usually make a lot of sense and they just have problems implementing their idea.
My best word of advice is it takes a lot of practice, and the more you program the better you will understand it.
In a sense, you can consider "pointers" to be one of the two most fundamental types in software - the other being "values" (or "data") - that exist in a huge block of uniquely-addressable memory locations. Think about it. Objects and structs etc don't really exist in memory, only values and pointers do. In fact, a pointer is a value too....the value of a memory address, which in turn contains another value....and so on.
So, in C/C++, when you declare an "int" (intA), you are defining a 32bit chunk of memory that contains a value - a number. If you then declare an "int pointer" (intB), you are defining a 32bit chunk of memory that contains the address of an int. I can assign the latter to point to the former by stating "intB = &intA", and now the 32bits of memory defined as intB, contains an address corresponding to intA's location in memory.
When you "dereference" the intB pointer, you are looking at the address stored within intB's memory, finding that location, and then looking at the value stored there (a number).
Commonly, I have encountered confusion when people lose track of exactly what it is they're dealing with as they use the "&", "*" and "->" operators - is it an address, a value or what? You just need to keep focused on the fact that memory addresses are simply locations, and that values are the binary information stored there.
There's no substitute for practicing.
It's easy to read through a book or listen to a lecture and feel like you're following what's going on.
What I would recommend is taking some of the code examples (I assume you have them on disk somewhere), compile them and run them, then try to change them to do something different.
Add another subclass to a hierarchy
Add a method to an existing class
Change an algorithm that iterates
forward through a collection to go
backward instead.
I don't think there's any "silver bullet" book that's going to do it.
For me, what drove home what pointers meant was working in assembly, and seeing that a pointer was actually just an address, and that having a pointer didn't mean that what it pointed to was a meaningful object.
The best book I've read on these topics is Thinking in C++ by Bruce Eckel. You can download it for free here.
For classes:
The breakthru moment for me was when I learned about interfaces. The idea of abstracting away the details of how you wrote solved a problem, and giving just a list of methods that interact with the class was very insightful.
In fact, my professor explicitly told us that he would grade our programs by plugging our classes into his test harness. Grading would be done based on the requirements he gave to us and whether the program crashed.
Long story short, classes let you wrap up functionality and call it in a cleaner manner (most of the time, there are always exceptions)
One of the things that really helped me understand these concepts is to learn UML - the Unified Modeling Language. Seeing concepts of object-oriented design in a graphical format really helped me learn what they mean. Sometimes trying to understand these concepts purely by looking at what source code implements them can be difficult to comprehend.
Seeing object-oriented paradigms like inheritance in graphical form is a very powerful way to grasp the concept.
Martin Fowler's UML Distilled is a good, brief introduction.
Pretend a pointer is an array address.
x = 500; // memory address for hello;
MEMORY[x] = "hello";
print MEMORY[x];
its a graphic oversimplification, but for the most part as long as you never want to know what that number is or set it by hand you should be fine.
Back when I understood C I had a few macros I had which more or less permitted you to use pointers just like they were an array index in memory. But I've long since lost that code and long since forgotten.
I recall it started with
#define MEMORY 0;
#define MEMORYADDRESS( a ) *a;
and that on its own is hardly useful. Hopefully somebody else can expand on that logic.
Classes are relatively easy to grasp; OOP can take you many years. Personally, I didn't fully grasp true OOP until last year-ish. It is too bad that Smalltalk isn't as widespread in colleges as it should be. It really drives home the point that OOP is about objects trading messages, instead of classes being self-contained global variables with functions.
If you truly are new to classes, then the concept can take a while to grasp. When I first encountered them in 10th grade, I didn't get it until I had someone who knew what they were doing step through the code and explain what was going on. That is what I suggest you try.
To better understand pointers, I think, it may be useful to look at how the assembly language works with pointers. The concept of pointers is really one of the fundamental parts of the assembly language and x86 processor instruction architecture. Maybe it'll kind of let you fell like pointers are a natural part of a program.
As to classes, aside from the OO paradigm I think it may be interesting to look at classes from a low-level binary perspective. They aren't that complex in this respect on the basic level.
You may read Inside the C++ Object Model if you want to get a better understanding of what is underneath C++ object model.
The point at which I really got pointers was coding TurboPascal on a FatMac (around 1984 or so) - which was the native Mac language at the time.
The Mac had an odd memory model whereby when allocated the address the memory was stored in a pointer on the heap, but the location of that itself was not guaranteed and instead the memory handling routines returned a pointer to the pointer - referred to as a handle. Consequently to access any part of the allocated memory it was necessary to dereference the handle twice. It took a while, but constant practice eventually drove the lesson home.
Pascal's pointer handling is easier to grasp than C++, where the syntax doesn't help the beginner. If you are really and truly stuck understanding pointers in C then your best option might be to obtain a copy a a Pascal compiler and try writing some basic pointer code in it (Pascal is near enough to C you'll get the basics in a few hours). Linked lists and the like would be a good choice. Once you're comfortable with those return to C++ and with the concepts mastered you'll find that the cliff won't look so steep.
Did you read Bjarne Stroustrup's The C++ Programming Language? He created C++.
The C++ FAQ Lite is also good.
You may find this article by Joel instructive. As an aside, if you've been "working in C++ for some time" and have graduated in CS, you may have gone to a JavaSchool (I'd argue that you haven't been working in C++ at all; you've been working in C but using the C++ compiler).
Also, just to second the answers of hojou and nsanders, pointers are very fundamental to C++. If you don't understand pointers, then you don't understand the basics of C++ (acknowledging this fact is the beginning of understanding C++, by the way). Similarly, if you don't understand classes, then you don't understand the basics of C++ (or OO for that matter).
For pointers, I think drawing with boxes is a fine idea, but working in assembly is also a good idea. Any instructions that use relative addressing will get you to an understanding of what pointers are rather quickly, I think.
As for classes (and object-oriented programming more generally), I would recommend Stroustrups "The C++ Programming Language" latest edition. Not only is it the canonical C++ reference material, but it also has quite a bit of material on a lot of other things, from basic object-oriented class hierarchies and inheritance all the way up to design principles in large systems. It's a very good read (if not a little thick and terse in spots).
Pointers are not some sort of magical stuff, you're using them all the time!
When you say:
int a;
and the compiler generates storage for 'a', you're practically saying that you're declaringan int and you want to name its memory location 'a'.
When you say:
int *a;
you're declaring a variable that can hold a memory location of an int.
It's that simple. Also, don't be scared about pointer arithmetics, just always
have in mind a "memory map" when you're dealing with pointers and think in terms
of walking through memory addresses.
Classes in C++ are just one way of defining abstract data types. I'd suggest reading a good OOP book to understand the concept, then, if you're interested, learn how C++ compilers generate code to simulate OOP. But this knowledge will come in time, if you stick with C++ long enough :)
Your problem seems to be the C core in C++, not C++ itself. Get yourself the Kernighan & Ritchie (The C Programming Language). Inhale it. It's very good stuff, one of the best programming language books ever written.