0

I'm having an odd problem. I have a practice exercise with pointers and the results are coming out differently depending on the order of cout statements. Depending on of the two struct variables I cout first, they come out differently. More specifically, the struct Student has two variables, name and gpa. After setting up the variables, if I cout gpa then name, gpa is fine and name is not; if I cout name then gpa, name is fine and gpa is not. Any idea why?

This is the code, with name then gpa output:

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

struct Student
{
    char * name;
    float gpa;
};

Student *createStudent(char name[], float gpa);

int main()
{
    int     MAX = 100;
    float   stuGpa = 0;
    char    *stuName = new char[MAX];

    cout << fixed << setprecision(2);

    stuName = "fubar";
    stuGpa = 4.0;

    Student *student1;
    student1 = new Student;
    student1 = createStudent(stuName, stuGpa);

    // cout name (first)
    cout << "\nStudent name is " << student1->name;

    // cout gpa (second)
    cout << "\nStudent gpa is " << student1->gpa;

    return 0;
}

Student *createStudent(char name[], float gpa)
{
    int length = strlen(name);
    Student newStudent;
    newStudent.gpa = gpa;
    newStudent.name = new char[length];
    newStudent.name = name;
    return &newStudent; //return the address of the newly created student
}

My output:

Student name is fubar
Student gpa is 0.00

If I reverse the cout statements, the output is

Student gpa is 4.00
Student name is 

Any idea why the cout order is affecting the content of the struct variables?

Potato_potato
  • 89
  • 1
  • 5
  • 1
    you should really read the [compiler warnings](http://melpon.org/wandbox/permlink/mFk7JIrfAqvNwBYc) – m.s. Aug 08 '15 at 07:49

1 Answers1

3

Yes, you are returning the address of a local variable:

Student *createStudent(char name[], float gpa)
{
    Student newStudent; // <-------- here
    return &newStudent; //return the address of the newly created student
}

The newly-created student only lives so long as the createStudent function is executing . It gets destroyed when } is reached. You returned a pointer to an object that no longer exist.

You also have a memory leak in the main function:

student1 = new Student;   // point "student1" to a newly allocated Student
student1 = createStudent(stuName, stuGpa);  // point it elsewhere

The object created by "new" no longer has any pointers to it, because you made "student1" point elsewhere.

There is another such leak in:

stuName = new char[MAX];    // point stuName at some allocated memory
stuName = "fubar";          // point stuName at "fubar" instead

This is the sort of mess you get into when using pointers and new.

To fix this mess your best option is to make the following changes:

  • Return Student, not Student *
  • Use Student , not Student * in the main function
  • Change char * name to std::string name
  • Change char *stuName = new char[MAX]; to std::string stuName;
M.M
  • 138,810
  • 21
  • 208
  • 365
  • Thanks for pointing out my noob mistake with the local instance of student1 in createStudent. Unfortunately, I can't get rid of the pointers because they're part of the assignment (and I really prefer working with strings, so I'd love to take your advice), so I moved the Student initialization into main and added a parameter to createStudent to pass the Student pointer to it. – Potato_potato Aug 08 '15 at 08:20