Objects and Pointers

Some of the previous videos and reading have covered the implications of an object owning some dynamically allocated memory.  Mainly, what I’m referring to here is the need for a copy constructor, overloaded assignment operator, and destructor in a class that contains any dynamically allocated memory.  That’s all important stuff.  Know it, learn it, love it.

But what about the dynamic allocation of objects themselves – how does it work and what are the implications.  I’m glad you asked. Dynamically allocating an object is just like dynamically allocating anything else.   [Read more…]

Object-Oriented Programming in C++

C++ was originally called “c with classes” meaning that it was everything that the c language was plus the ability to create classes and objects in the language.  I’m sure that you can see the value in creating a higher level construct over and above a simple variable.  For example, if we were modeling the data for a group of workers at a company, we would want to keep track of a number of different things about each employee: name, address, employee id number, yearly salary, and department perhaps.  We could make use of the concept of parallel arrays meaning that we have 2 or more arrays whose elements are related via their position (or subscript) in the array.  So, name[9], empID[9], salary[9], etc would all refer to data about the same employee because each is being accessed with the same subscript.  However, after a while, this becomes cumbersome and isn’t very extensible as we add new variables to track.  [Read more…]

Arrays of c-strings

There are a lot of use cases in which you deal with a set of strings.  An array of strings seems to be a logical, first-pass choice for storing them.  Because c-strings are basic arrays fundamentally, they are a great topic to use to understand the array/pointer relationship more fully.

Consider, the following array declaration:

char data[5][10] = {"red", "yellow", "green", "blue", "violet"};

Because data is the name of a 2D array, it can be treated as a pointer to a pointer, or more precisely in this case, a pointer to an array of pointers.  Because we are dealing with a 2D array of chars with each row acting as a null-terminated c-string, then we can also conceptualize data as an array of c-strings.  So, if I have an array of c-strings, then I can display just one c-string from the array by sending the address of the 1st element of the array to cout like this:

cout << data[1] << endl; //would print yellow

Remember, if you send an ostream object a char pointer, it will start printing at that character until it gets to a null terminator.  This means that if we send it the address of the first letter of a row and an additional offset (but not subscripted), it will start printing at that letter and go to the null terminator as well.  Here is an example:

cout << data[2] + 2 << endl; //would print een of green

The expression data[2]+2 is the memory address of the 3rd character in the 3rd string of the array.  Therefore, it will start printing at that character and print until the end of the string.

You may be asking yourself, “What’s the difference between the example above and data[2][2]?”  Great question!  The difference is that in data[2][2], the 2nd number is subscripted, which means essentially that it is dereferenced.  So, the data type of the expression data[2]+2 is char* while the data type of the expression data[2][2] is char.  If we send cout a char, it will only print that one character.

Pointer Offset Notation and Subscript Notation

As we know,

data[2]

is equivalent to

*(data + 2)

One first is subscript notation, then second is pointer-offset notation.  We can include multiple levels of offsets depending on the data type of the base constructs (the datatype of data, in this case).  So, this means that the expression

data[2][2]

is equivalent to the expression

*(*(data + 2)+2)

If you think about starting at the deepest level of nesting and work your way out, you’ll see that they are equivalent.

As an example, the following two statements produce the same output:

cout << (data[1] + 3) << endl;
cout << (*(data+1)+3) << endl;

The relationship between pointer-offset notation and subscript notation can seem to be a little confusing.  But if you just take it slow, it all makes logical sense.

Peace, love, c++!

Memory Management in C++

C++ gives you, the programmer, more fine-grained access to memory than a language like Java.  An old saying goes like this, “To whom much is give, much is expected.”  So, because you have more control over memory, you have to take care to handle it appropriately.  This means that if you dynamically allocate memory, you should de-allocate it when you’re done with it.

Here are a few YouTube videos that are similar to stuff I’ve talked about.  But hearing the info explained a little differently might be helpful.

Basic Dynamic Allocation and Deallocation:  Video

Memory Leaks and Dangling Pointers: Video (The writing is a little bit hard to read, but it is a good explanation)

Pointers to Pointers: Video (Same issue as above, but good expl).

It’s Not Nice to Point… But Really, It’s OK.

Pointers are really important to the C and C++ language.  They are actually really important in many different languages whether or not you have direct access to manipulate them. In our on-line gathering yesterday evening, I introduced you to the basic concepts of pointers and memory layout, well – at least how C++ sees it.

It’s time to read Section 6.3 of Overland (skip 6.3.7, 6.3.8 and 6.3.9). Also read Section 6.4, but stop before the paragraph that starts with “This analysis—what would the item imply…”.  From that point down is about function pointers which should be in its own sub section.  But in any event, you don’t need to worry about these. 

Here are a couple videos that might also be useful to you that I made a few semesters ago: Video 1, Video 2.

Reading sections 10.1, 10.2, and 10.3 of Overland related to c-strings could be helpful if you need more info there.

2 Dimensions are Better than 1, right?

Many problems deal with more than single dimensional data.  At the risk of beating the grade example to pieces, think about the idea of a class having 20 students and 4 exam grades for a semester.  Would it be possible to model this scenario with a 1D array?  Sure, absolutely.  Would it be fun?  Very unlikely.  Another example that you work with every day is graphics. [Read more…]

Arrays – A Ray of Sunshine for your Programs

Arrays are a foundational data structure in many programming languages, especially those that come from the same genre as c++.  However, different languages treat arrays different, meaning that they have different “features”. [Read more…]

Design before Coding

In the “real world”, it is a rare occurrence that a developer encounters a problem and starts to solve that problem with a blank project.  Often times, a dev is working as part of a much larger contingent of folks on a much more massive software project.  It doesn’t really make sense that you’d just walk in to that space and start hacking away on code without first attempting, at least in some small way, to wrap your brain around [Read more…]

Fun Times with File I/O in C++

You use files every day; don’t deny it!  From the perspective of a program that you may write, a file is a way to have persistent storage.  What I mean by this is that the data you put in the file persists beyond the execution of the program.  So, if while your program is running, you put some data of some sort in your file, then when you run your program again tomorrow, that data should still be there.  Pretty much every program you use on a daily basis uses files.  Cool, right? Yea!

A Tad Bit of Background

From your previous programming experience, you probably remember the word inheritance.  Without going into the [Read more…]

More of Functions in C++

There are a few things that aren’t really covered in the Overland text related to functions – at least not in chapter 5 – that are very important to understand.

As a note, I very (very very very) frequently use different terminology for the variables that are part of the function header vs. function call.  Here’s my explanation of the two:

  • function parameters:  the “things” listed in the function header or function prototype.  They accept values from the function call. You may see these referred to as “formal parameters”.
  • function argument:  these are the values that are listed in a function call, sometimes literal values, sometimes variables. You may occasionally see these referred to as “actual parameters”.

What Happens When you Call a Function

So, functions are important in C++.   [Read more…]