CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Sep 2011
    Posts
    4

    [RESOLVED] Array of objects - member variable in free store error

    #include<iostream.h>
    #include<string.h>

    class Employee{
    protected:
    char* name;
    public:
    Employee(){ // Default constructor used to declare arrays
    name="empty";
    cout << "Default constructor called for " << name << endl;
    }
    Employee(char* name_1){
    name=new char[strlen(name_1)+1];
    name=name_1;
    cout << "Explicit constructor called for " << name << endl;
    }
    ~Employee(){
    delete [] name;
    cout << "Destructor called for " << name << endl;
    }
    char* show(){return name;}
    };
    int main(){
    cout << "----------------------" << endl;
    Employee Executive[2];
    Executive[0]=Employee("Alex");
    Executive[1]=Employee("Mery");
    cout << "your user is " << Executive[0].show() << endl;
    cout << "your user is " << Executive[1].show() << endl;
    return 0;
    }
    ------------------------------------------------------------

    array is created and destroyed as soon as it created. Why ?
    There are other problems also what's wrong with this code ?

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,430

    Re: Array of objects - member variable in free store error

    Quote Originally Posted by san1 View Post
    array is created and destroyed as soon as it created. Why ?
    There are other problems also what's wrong with this code ?
    The first thing you did wrong is you did not formatted your code properly, so it is very hard to read/understand it.

    As for you problem: did you try to debug your code, particularly this line:
    Code:
    Executive[0]=Employee("Alex");

    Just set a break point, press F5, then F11... (in MS IDE)
    Victor Nijegorodov

  3. #3
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Array of objects - member variable in free store error

    First, please use code tags when posting code. The code you posted is not formatted and very hard to read.

    There are a few things wrong with your code, and a few things you need to learn about C++ and object creation:

    1)
    Code:
    #include<iostream.h>
    The correct header is <iostream>, not <iostream.h>. There is no such header as <iostream.h> in ANSI C++.

    After including <iostream>, then I/O classes are in the std namespace.

    I can bomb your code out with just one line main()
    Code:
    int main()
    {
       Employee e;
    }
    Do you know why it bombs out? Because you are attempting to delete[] the name, and the name was not dynamically allocated in the destructor of Employee.

    So before even explaining what's wrong with your code, if a one-line program doesn't work, it would make sense to fix that before even going on any further.

    Your Employee class not only has that error, it lacks a copy constructor and assignment operator that will handle the pointer to dynamically allocated memory. There are literally hundreds of threads on this topic, and should have been discussed in the C++ book you're using.

    Having said this, the easy way to not have these issues is to use std::string instead of char pointers and new[]/delete[]. There is no reason to be using new[]/delete[] in any C++ program, except for the case if you're creating your own memory allocator. For string data, std::string makes everything work correctly.
    Code:
    #include <string>
    class Employee
    {
        protected:
        std::string name;
    
        public:
            Employee(const std::string& sName = "empty") : name(sName) { }
    };
    That entire code is all you need, and everything works correctly.

    Regards,

    Paul McKenzie

  4. #4
    Join Date
    Sep 2011
    Posts
    4

    Re: Array of objects - member variable in free store error

    Sorry to everyone guys for bad formatted code. I will format code properly when I post something in future. I compiled this code in Turbo C just to be quick.
    Anyway thanks for your quick response.

  5. #5
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Array of objects - member variable in free store error

    Please use [code][/code] tags around code when posting, else you lose the formatting and it becomes difficult to read.

    There are a number of things wrong with your program. So what I will do is re-print your code with code tags and put some numbers against the items that have issues

    Code:
    #include<iostream.h> //1
    #include<string.h>  //2
    
    class Employee
    {
    protected:
      char* name;
    public:
      Employee()
      { // Default constructor used to declare arrays
        name="empty"; //3
        cout << "Default constructor called for " << name << endl;
      }
    
      Employee(char* name_1)
      {
        name=new char[strlen(name_1)+1];
        name=name_1; //4
        cout << "Explicit constructor called for " << name << endl;
      }
      
      ~Employee()
      {
        delete [] name;
        cout << "Destructor called for " << name << endl;
      }
      
      char* show(){return name;}
    };
    
    int main()
    {
      cout << "----------------------" << endl;
      Employee Executive[2];
      Executive[0]=Employee("Alex");
      Executive[1]=Employee("Mery");
      cout << "your user is " << Executive[0].show() << endl;
      cout << "your user is " << Executive[1].show() << endl;
      return 0;
    }
    Here are my comments

    1) iostream.h is not a standard C++ header and should not be used. The correct standard header is iostream, therefore the correct include declaration is:
    Code:
     #include <iostream>
    2) string.h is not a C++ header. The correct header is
    Code:
     #include <cstring>
    3) When you write the following
    Code:
     name = "empty"
    you are assigning a string literal to a pointer. A string literal has static storage duration, and attempting to call the delete[] expression on a pointer pointing to a string literal will yield undefined behaviour. With the exception of setting the pointer to null, if you are going to use the pointer for dynamic allocation and deallocation then you should not use it for pointing to anything other than memory that you allocate and deallocate with that pointer. The point is, be consistent, otherwise you will get yourself in trouble. So what you can do is allocate some memory to name using new[] and then assign "empty" to it.

    4) The following line does not do what you think:
    Code:
    name=name_1;
    What it is doing is assigning the name_1 pointer to the name pointer, what it is not doing is assigning the contents of memory pointed to by the name_1 pointer, to the contents of the memory pointed to by the name pointer. In order to do that, you need to use memcpy. Passing a null pointer to memcpy yields undefined behaviour, so you will first need to check that name_1 is not null before attempting a copy. So, in short, the above line should be changed to something along the lines of:

    Code:
    if(name_1 != 0)
    {
      memcpy(name, name_1, strlen(name_1));
    }
    else
    {
      //Do something in here
    }
    Finally, you could save your self a lot of trouble just by using the standard string class:

    Code:
    #include<iostream>
    #include<string>
    
    class Employee
    {
    protected:
      std::string name;
    public:
      Employee()
      { // Default constructor used to declare arrays
        name="empty";
        cout << "Default constructor called for " << name << endl;
      }
    
      Employee(char* name_1)
      {
        name=name_1; 
        cout << "Explicit constructor called for " << name << endl;
      }
        
      const char* show() const {return name.c_str();}
    };
    
    int main()
    {
      cout << "----------------------" << endl;
      Employee Executive[2];
      Executive[0]=Employee("Alex");
      Executive[1]=Employee("Mery");
      cout << "your user is " << Executive[0].show() << endl;
      cout << "your user is " << Executive[1].show() << endl;
      return 0;
    }
    EDIT:
    Just for information, I posted the above having not seen Paul response - although I guess that might be obvious .
    Last edited by PredicateNormative; December 11th, 2011 at 12:44 PM.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Array of objects - member variable in free store error

    Quote Originally Posted by san1 View Post
    Sorry to everyone guys for bad formatted code. I will format code properly when I post something in future. I compiled this code in Turbo C just to be quick.
    That compiler is over 20 years old!. You shouldn't even consider compiling anything using that dinosaur. It is not ANSI compliant, and any advice we give you may not even work or be implemented with such an old compiler.

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: Array of objects - member variable in free store error

    Just to mention...

    Quote Originally Posted by PredicateNormative View Post
    Code:
      memcpy(name, name_1, strlen(name_1));
    That's the same as:

    Code:
      strcpy(name, name_1);
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  8. #8
    Join Date
    Sep 2011
    Posts
    4

    Re: Array of objects - member variable in free store error

    I understand the error no. 1, 2 and 4.
    But error no. 3 is somewhat confusing to me.
    I have some questions
    1)
    Why array elements Executive[0] and Executive[1] are destroyed as soon as they are created. I have learned that objects gets

    destroyed when goes out of scope or memory which is allocated in free store, need to be free .
    2)
    I have dynamically allocated only array elements Executive[0] and Executive[1] in free store, not Executive[]. So my

    assumption is, only Executive[0] and Executive[1] should call destructor not the Executive[].

    If you think I should do some homework before asking stupid questions like this then please suggest me any resources on web.
    Or if you correct the code I might understand something.

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Array of objects - member variable in free store error

    Quote Originally Posted by san1 View Post
    I understand the error no. 1, 2 and 4.
    But error no. 3 is somewhat confusing to me.
    I have some questions
    1)
    Why array elements Executive[0] and Executive[1] are destroyed as soon as they are created.
    You are doing many things in two lines of code.
    Code:
    Employee Executive[2];
    This constructs two Employee objects. The default constructor is called for each object.
    Code:
    Executive[0]=Employee("Alex");
    You are constructing a temporary object, Employee("Alex"). Then, this temporary is assigned to element 0 of the array, calling the assignment operator to do this (the "=") . Then the temporary is destroyed (the destructor of the item in the right side of the equal sign is called).

    In other words, if you break the second-line down:
    Code:
    1)  Employee("Alex");  // creates temporary Employee, let's call it T.
    
    2)  Executive[0] =  T; // calls assignment operator to assign temporary T to Executive[0].  The "=" is responsible for this magic.
    
    3) ~T(); //  called by the compiler.  Temporary goes away, so destructor for Employee("Alex") is called
    So you are not just doing simple assignment, as if you're working with arrays of ints or doubles. Construction, assignment, constructing temparies, destruction, are done on just those two lines. That's why it is important to write a user-defined copy constructor and assignment operator. You don't know when or where it will be called, and the code above proves my point.

    But you can forget all of this if you just used std::string.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; December 12th, 2011 at 11:18 AM.

  10. #10
    Join Date
    Sep 2011
    Posts
    4

    Re: Array of objects - member variable in free store error

    Thank's Paul, Predicate and other guys.
    Paul, you had already mentioned that I need assignment operator and copy constructor, but I simply overlooked assignment operator and thought that both are not necessary here.

    Thanks everyone guys.

  11. #11
    Join Date
    May 2007
    Location
    Scotland
    Posts
    1,164

    Re: Array of objects - member variable in free store error

    Quote Originally Posted by Eri523 View Post
    Just to mention...



    That's the same as:

    Code:
      strcpy(name, name_1);
    Yeah, I kind of forgot about strcpy.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured