Jump to content
  • Advertisement
Sign in to follow this  
Theodore Fuhringer

C++ Programming Exercise I can't work out

This topic is 4840 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I'm working on a programming exercise in the book C++ Primer Plus by Stephen Prata. I managed the first two parts of the exercise but I can't for the life of me figure out how to do the third part, and I've reread the chapter several times. Here's the whole exercise: "The CandyBar structure contains three members. The first member holds the brand name of a candy bar. The second number holds the weight (which may have a fractional number) of the candy bar, and the third member holds the number of calories (an integer value) in the candy bar. Write a program that decalres such a structure and creates a CandyBar variable called snack, initializing its parameters to "Mocha Munch", 2.3, and 350 respectively. The initialization should be part of the declaration for snack. Finally the program should display the contents of the snack variable." Ok, I did all that and moved on to the next part... "The CandyBar structure contains three members, as described in the previous exercise. Write a program that creates an array of three CandyBar structures, initializes them to values of your choice, and then displays the contents of each structure." Ok, I did that... but now this last part has me totally stumped. "Do the previous programming exercise, but, instead of declaring an array of three CandyBar structures, use "new" to allocate the array dynamically." What?!? Any help would be greatly appreciated, thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
You will have to declare a pointer to your candy bar structure.

To dynamically allocate your structure:


struct candyBar
{
std::string name;
int calories;
float weight;
};

int main(void)
{
//declare a pointer and allocate your memory
candyBar* pCandy = new candyBar[3];
//to access your dynamically created array of candy bars(mmm candy bars)
pCandy[0].calories = 100;
pCandy[0].name = "yo";
pCandy[0].weight = 12.6;
//Just in case, [0] only accesses the first element in your
//candyBar array

//Don't forget to clean up after yourself
delete[] pCandy;
return 0;
}






This declares a pointer to a dynamically allocated array of structs (your candyBars)

Share this post


Link to post
Share on other sites
Quote:
Original post by Theodore Fuhringer
"Do the previous programming exercise, but, instead of declaring an array of three CandyBar structures, use "new" to allocate the array dynamically."


Old:

CandyBar myBars[3];

New:

CandyBar* myBars = new CandyBar[3];

(Read the chapter again; it really should have explained exactly how to do this, assuming normal "textbook practices".)

In both cases here, the name "myBars" can be used as a pointer to a chunk of memory that contains 3 CandyBars, one after the other in a nice, neat block. (However, in the dynamic case we have already "degraded" to a pointer, and the extra type information that an array normally provides is no longer there. That is, 'sizeof(myBars)' will evaluate to 3 times the size of the CandyBar struct in the array case, but it will evaluate to 4 - for typical systems - in the 'new' case: i.e., the size of the pointer.)

The difference is that the dynamic allocation (with 'new') is using the heap, and it won't clean up automatically because there is no automatic time at which that should happen - the intent is that you can have data that persists as long as it needs to, but you're still responsible for putting your toys away:

delete[] myBars; // at the appropriate time

Be careful:

1) delete, and delete[], really clean up the thing that is being pointed at. Here, "myBars" is a pointer on the stack, that points to an array on the heap. When we delete[], the array's storage is returned to the system. The pointer itself is cleaned up automatically at the end of the function, because it's a local variable (thus "on the stack").
2) Consequently, you can have multiple pointers in your program that point to your memory allocation (whether they are locals, globals or themselves elsewhere on the heap - perhaps embedded in other structs!). You need to make sure that the allocation gets deleted exactly once, at runtime (when you say you don't want something any more, saying it again can confuse the system), and that none of the pointers to the allocation will ever be dereferenced after the deletion (when you say you don't want something any more, the system takes it away and it's gone, and trying to grab it again could do basically anything).
2a) You CAN safely use delete with a null pointer; as a special case, it does nothing. You CANNOT use it with an invalid, or uninitialized pointer. (In point 2, after deleting something once, all pointers that exist to it are now "invalid"). You may find it is good practice to set a pointer to NULL after deleting via it.
3) You MUST use delete[] for something that was allocated as an array, and delete for something that was allocated as a single object. They do different things, and Anything Could Happen(TM) if the wrong deletion is used. Unfortunately, pointers have no way of knowing or "remembering" what sort of allocation they point to; that's your responsibility.

An important skill for programmers is to be able to think about the "run-time structure" of a program - how objects will link to each other in memory, who "owns" what dynamic allocation (i.e. will be responsible for cleaning it up) and generally when things will happen. This is rather different from the compile-time structure (the source file organization, what functions call which other functions etc).

In general, memory management gets to be a pain. Fortunately, the standard library provides tools for dealing with allocations more simply - basically, they let you treat the allocations as if they were just objects on the stack, by making use of object "destructors" (you should do this too, and if your book - I don't know it - is any good, you will learn how to in good time) to manage a memory allocation that "belongs" to a plain object (as opposed to a pointer to something) which you then use like any normal local variable.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!