it compiles, but...

B

Bimo Remus

Hi, I'm having problems with an assignment. We're supposed to take an
old assignment and rewrite it so that each task is carried out by a
different function. I just started this afternoon but have already
run into a wall.

When I try to compile the program, it seems to work, but after the
first cin, an error message pops up and it crashes. It might have
something to do with the pointers, seeing how I am still very shaky on
them (I'm also a little shaky on when to use some things with
functions), but I don't know.

And I should add that I am a student so I would appreciate it if
someone could point me in the right direction without telling exactly
what to do... but any help is much appreciated.

Thanks, Bimo

#include <iostream>
#include <cstdio>
using namespace std;

// prototype for a function that gets name and stores it
char *getName(void);

int main() {
char *person;
int month;
double years; // number of years invested
double rate; // yearly interest rate
double inv; // total investment

// collects customer information
person = getName();
cout << "Enter the initial investment ammount: ";
cin >> inv;
cout << "Enter interest rate: ";
cin >> rate;
cout << "How many years will the money be invested?: ";
cin >> years;

// calculate compounded investment
cout << "Investment table if " << inv << " at " << rate << "% for ";
cout << years << " years for " << person << " is:\n\n";
cout << "Year Monthly compounded\n";
for(int count = 0; count != years; count++)
for( month=1; month <= 12; month++) {
inv += inv * (rate/100/12);
if(month == 12) cout << " " << count + 1 << " " << inv << "\n";
}

return 0;
}

/* the Function, getName, asks the user for name and uses gets()
to store it in a character array.
Parameters: none
Return Values: *char

*/
char *getName(void) {
char *person; // this holds the string returned by *getname()
static char name[80];

cout << "Enter your name: ";
gets(person); // gets the name

return person; //returns result
}
 
J

John Tsiombikas (Nuclear / the Lab)

And I should add that I am a student so I would appreciate it if
someone could point me in the right direction without telling exactly
what to do... but any help is much appreciated.

I'm glad you see it this way, most students that I know try to copy
blindly programs from other students who know some things.... And they
end up knowing nothing.

char *getName(void) {
char *person; // this holds the string returned by *getname()

this is a local variable, it becomes invalid when you exit the function,
but this is not your immediate problem... (see last comment)
static char name[80];

cout << "Enter your name: ";
gets(person); // gets the name

You must pass enough allocated space to gets in order to work, it does
not allocate a buffer for you. You just pass an unitinialized pointer
that may point anywhere so it crashes when gets() tries to dereference
it and store some data there.
return person; //returns result

also the pointer that you return here is invalid when the function exits
and your main program will try to use an invalid pointer.

-- Nuclear / the Lab --
 
J

John Harrison

Bimo Remus said:
Hi, I'm having problems with an assignment. We're supposed to take an
old assignment and rewrite it so that each task is carried out by a
different function. I just started this afternoon but have already
run into a wall.

When I try to compile the program, it seems to work, but after the
first cin, an error message pops up and it crashes. It might have
something to do with the pointers, seeing how I am still very shaky on
them (I'm also a little shaky on when to use some things with
functions), but I don't know.

And I should add that I am a student so I would appreciate it if
someone could point me in the right direction without telling exactly
what to do... but any help is much appreciated.

[snip]

char *getName(void) {
char *person; // this holds the string returned by *getname()
static char name[80];

cout << "Enter your name: ";
gets(person); // gets the name

return person; //returns result
}

person is an uninitialised pointer. Using person is guaranteed to give you
problems.

There are two sensible ways to write functions like this, the simple way is
to use a string

string getName()
{
cout << "Enter your name ";
string name;
getline(cin, name);
return name;
}

Couldn't really be simpler.

The complicated way is to pass a pointer to the memory you are using to hold
the name into the function

void getName(char* name)
{
cout << "Enter your name ";
gets(name);
}

This is awkward, dangerous (no check on the length of the name entered), but
some people prefer it.

The way that doesn't work is this

char* getName()
{
cout << "Enter your name ";
char name[99];
gets(name);
return name;
}

Because the array name ceases to exist when the function exits, therefore
you end up with a pointer that isn't pointing at anything meaningful.

Another bad way is this

char* getName()
{
cout << "Enter your name ";
static char name[99];
gets(name);
return name;
}

Now the addition of static stops the array ceasing to exist when the
function exits, but you have the serious problem that only a single name can
exist. Seemingly sensible code like this will fail

int main()
{
char* name1 = getName();
char* name2 = getName();
cout << name1 << ' ' << name2;
}

Only a single name array, therefore this program will print out the same
name twice (the second one entered).

My advice would be to use a string.

john
 
B

Bimo Remus

Thanks for the response. Here are some more questions:

John Tsiombikas (Nuclear / the Lab) said:
I'm glad you see it this way, most students that I know try to copy
blindly programs from other students who know some things.... And they
end up knowing nothing.



this is a local variable, it becomes invalid when you exit the function,

I thought that the way I had it, the variable, *person, from the
function, *getName(), was pointing to the memory address of the string
returned by gets(). Then that memory address was returned to another
variable, also named *person, which is in the main function. Do I not
get it?
but this is not your immediate problem... (see last comment)
static char name[80];

cout << "Enter your name: ";
gets(person); // gets the name

You must pass enough allocated space to gets in order to work, it does
not allocate a buffer for you. You just pass an unitinialized pointer
that may point anywhere so it crashes when gets() tries to dereference
it and store some data there.

So - gets(person[80]); - would work?

or maybe - gets(gets[]); - ?
also the pointer that you return here is invalid when the function exits
and your main program will try to use an invalid pointer.

Hmmm, I see... Here again, I thought that the function's person would
come back to main() as the result of getName(). - person = getName();
-
If that doesn't work, how do I do it?
Thanks again and I should tell you that my computer had a meltdown
last night and I don'tknow what I have to do to fix it (I'm using my
girlfriend's computer now) so I don't have access to a compiler right
now... but I need to keep this stuff fresh in my mind.
-- Nuclear / the Lab --


Thanks, Bimo
 
B

Bimo Remus

Thanks, John. Questions below.

John Harrison said:
Bimo Remus said:
Hi, I'm having problems with an assignment. We're supposed to take an
old assignment and rewrite it so that each task is carried out by a
different function. I just started this afternoon but have already
run into a wall.

When I try to compile the program, it seems to work, but after the
first cin, an error message pops up and it crashes. It might have
something to do with the pointers, seeing how I am still very shaky on
them (I'm also a little shaky on when to use some things with
functions), but I don't know.

And I should add that I am a student so I would appreciate it if
someone could point me in the right direction without telling exactly
what to do... but any help is much appreciated.

[snip]

char *getName(void) {
char *person; // this holds the string returned by *getname()
static char name[80];

cout << "Enter your name: ";
gets(person); // gets the name

return person; //returns result
}

person is an uninitialised pointer. Using person is guaranteed to give you
problems.

the compiler did give me a warning, but I couldn't wasn't sure what to
initialize it as... would - char *person = " "; - work?
There are two sensible ways to write functions like this, the simple way is
to use a string

string getName()
{
cout << "Enter your name ";
string name;
getline(cin, name);
return name;
}

Do I nees to use another library header for the type, string?

[snip]
My advice would be to use a string.

john

Thanks, John
 
J

John Harrison

Bimo Remus said:
Thanks, John. Questions below.

"John Harrison" <[email protected]> wrote in message
Bimo Remus said:
Hi, I'm having problems with an assignment. We're supposed to take an
old assignment and rewrite it so that each task is carried out by a
different function. I just started this afternoon but have already
run into a wall.

When I try to compile the program, it seems to work, but after the
first cin, an error message pops up and it crashes. It might have
something to do with the pointers, seeing how I am still very shaky on
them (I'm also a little shaky on when to use some things with
functions), but I don't know.

And I should add that I am a student so I would appreciate it if
someone could point me in the right direction without telling exactly
what to do... but any help is much appreciated.

[snip]

char *getName(void) {
char *person; // this holds the string returned by *getname()
static char name[80];

cout << "Enter your name: ";
gets(person); // gets the name

return person; //returns result
}

person is an uninitialised pointer. Using person is guaranteed to give you
problems.

the compiler did give me a warning, but I couldn't wasn't sure what to
initialize it as... would - char *person = " "; - work?

If you go 'char* person = " ";' your pointer is initialised but its
initialised to point to a literal string, when you read in the name the
chars of the name are going to overwrite the literal string (because that's
where the pointer is pointing). You are not allowed to modify a literal
string in this way, and in any case your literal string is very short, so
the name is going to write past the end of the literal string into who knows
where.

Every time you use a pointer you must think, where is this pointer pointing
to? Don't expect C++ to make it point somewhere useful for you, it won't.

E.g.

cout << "enter your name ";
char my_array[99];
char* person = my_array; // person is pointing at my_array
gets(person); // name will go into the my_array (because
thats where person is pointing)
Do I nees to use another library header for the type, string?

Yes the header is

#include said:
[snip]
My advice would be to use a string.

john

Thanks, John
 
J

John Harrison

Bimo Remus said:
Thanks for the response. Here are some more questions:



I'm glad you see it this way, most students that I know try to copy
blindly programs from other students who know some things.... And they
end up knowing nothing.



this is a local variable, it becomes invalid when you exit the function,

I thought that the way I had it, the variable, *person, from the
function, *getName(), was pointing to the memory address of the string
returned by gets(). Then that memory address was returned to another
variable, also named *person, which is in the main function. Do I not
get it?[/QUOTE]

You got it, John Tsiombikas got it wrong. The problem is that person is not
initialised.

Note that gets does not return anything, it uses the pointer you supply, it
does not return a pointer. That is why the pointer must be initalised BY
YOU.

The return of the pointer to a variable in main works fine, but things have
gone wrong before that.
but this is not your immediate problem... (see last comment)
static char name[80];

cout << "Enter your name: ";
gets(person); // gets the name

You must pass enough allocated space to gets in order to work, it does
not allocate a buffer for you. You just pass an unitinialized pointer
that may point anywhere so it crashes when gets() tries to dereference
it and store some data there.

So - gets(person[80]); - would work?

or maybe - gets(gets[]); - ?

Both of those are syntax errors.
Hmmm, I see... Here again, I thought that the function's person would
come back to main() as the result of getName(). - person = getName();

No again this is wrong. The problem with the function as you posted it was
the person was not initialised.

This is also wrong and may have been what John Tsiombikas was thinking of

char* getName()
{
char* person;
char name[80];
person = name;
gets(person);
return person;
}

Everything is fine until you return from the function. 'return person' is
not wrong, its just that in this case person *happens* to be pointing at an
array 'name' which ceases to exist when the function is exitted.

john
 
J

John Tsiombikas (Nuclear / the Lab)

You got it, John Tsiombikas got it wrong. The problem is that ... [clip] ..

Indeed, I wasn't thinking right when I posted this :)
thanks for correcting me, I hate it when people post irresponsibly wrong
answers without reading carefully and thinking straight especially since
the one who asked is in the process of learning. And yet I did it.
I appologize to the original poster.

-- Nuclear / the Lab --
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top