Hints for Project 3, CISC181, 06S
An question about parts 3-7
> Professor Conrad,
>
> I am not sure what I should do about parts 3 - 7. I have them completed
> showing examples of them in a seperate main function. However, they are
> not being used in my project 2 to project 3 conversion. For example, when i
> moved project 2 to project 3 I made a removeAll member function that deleted
> all the dynamically allocated memory. Now there is all the extra member
> functions created in parts 3 - 7, should I go back and change my print,
> delete, and copy constructor's in the conversion program?
You don't have to "demonstrate" the five new functions inside your
converted project 2---that can be done in one or more separate main
program(s)--but the five new functions should at least be "present"
in the .h and .cc files that you are compiling in with your finished
menu driven program. That is, in your final submission, there should
not be "one" set of .h and .cc files for parts 0-2, and a different
set for parts 3-7.
If everything is working now, what I'd suggest is that you make a tar
file with a backup of everything you currently have---so you have
something to submit in case something goes awry later---and then, take
a stab at trying to integrate your new functions into your code for
parts 0-2.
Things to keep in mind when integrating the new functionality in your
converted project 2:
(1) Keep in mind that the destructor gets called automatically when
the "list" variable in the main program goes out of scope. So, if you
are "manually" calling a function to recycle that memory, this could
be a problem, since you are recycling the memory twice. This can end
up "corrupting the heap".
(2) Also, if you have a pointer such as:
MyObject_C *p;
and inside that object, there is a char * field allocated from the
heap, such as:
p->name;
you do NOT want to BOTH do:
delete [] p->name;
delete p;
and ALSO have
delete [] name;
inside the destructor for the class MyObject_C. If you do that, you
are calling "free" twice on the "name" member of the object pointed to
by p. Calling "free" more than twice on the same piece of memory can
corrupt the heap.
I hope this helps. May I post this question and answer (anonymously)
to the web site?
> I have no problem with you posting the question...
>
> However, I did not understand the ...
> (2) Also, if you have a pointer such as:
>
> MyObject_C *p;
>
> and inside that object, there is a char * field allocated from the
> heap, such as:
>
> p->name;
>
> you do NOT want to BOTH do:
>
> delete [] p->name;
> delete p;
>
> and ALSO have
>
> delete [] name;
>
> inside the destructor for the class MyObject_C. If you do that, you
> are calling "free" twice on the "name" member of the object pointed to
> by p. Calling "free" more than twice on the same piece of memory can
> corrupt the heap.
>
>
> .... does this mean i only have to delete p and not delete the [] name?....
To clarify: you still have to
delete [] name;
What you DON'T want to do is do "delete [] name" inside your
destructor, AND also "delete [] p->name" somewhere else in your code.
Since doing "delete p;" automatically calls the destructor BEFORE it
returns p itself to the heap, if you do "delete [] name;" inside the
destructor, then that is automatically taken care of for you when you
do "delete p;".
Let me know whether that clears things up or not.
yes that clears everything up... thank you
An email question about making a constructor...
A CISC181 student wrote to me with this question---he gave me his
permission to share it with you, as well as my answer.
> Professor Conrad,
> ... a technical question on proj3:
>
> In Player_C (player.h file), can I overload the constructor, or do I
> always have to use the constructor...
>
> Player_C::Player_C(const char theFirstName[FIRST_NAME_LENGTH],
> const char theLastName[LAST_NAME_LENGTH],
> const char theTeamName[TEAM_NAME_LENGTH],
> int theNumber, int theKs, float theERA);
>
> This way, in my readPlayerFromFile(PlayerList_C list); function in main,
> I can just do Player_C p; which would make a crappy little p, then send p
> to parseInputLine(char *inputLine, Player_C *p);
> which assigns all the values to p by itself without making a bunch of
> un-needed "char blah[INSANELY_LONG_CONST_NAME];" declarations?
>
> Is this bad style, and do you even understand my question?
I do understand your question. You could do what you suggest. But
I'd suggest a better solution is this one:
Make an overloaded constructor as follows:
Player_C(char *inputLine);
Inside this constructor, do what you "would have done" inside parseInputLine.
This way, you don't have to create a---as you so eloquently put it---a
"crappy little p" object first, _and_ you also don't have to make all
those INSANELY_LONG_CONST_NAME declarations.
Having a constructor like this---one that can take a C-string that
contains a list of comma separated values and turn it into an object
(via strtok)--is a reasonably good approach.
In your main program, from your readFromFile() function, you can just
call that constructor inside your while loop, and pass the constructed
object into a "add" member function of your List class.
Regards,
Phill Conrad