Thread: Array allocation issue

  1. #1
    Software engineer
    Join Date
    Aug 2005
    Location
    Oregon
    Posts
    283

    Array allocation issue

    I have a class that has a pointer to an array of a generic type T.

    I created a copy constructor with the following code:

    Code:
    // Release the old array.
    if (m_array != NULL) 
    {
            delete [] m_array;
            m_array = NULL;
    }
    The issue with this is m_array has the value 0xcccccccc. So it hasn't been initialized. However, 0xcccccccc does not mean NULL, so it goes into the block. Now it's deleting an array that is not initialized still. I think this is due to MS's debugger where 0xcccccccc is suppose "to help you". Any idea how to avoid or work around this? Thanks.

    Since this may come up, it's a copy constructor. So I can do this: X x(a); or X x = a;

    So I can't just set m_array to NULL in the beginning because it may be already allocated. So I'm facing an array that may or may not be initialized...

    Here's how it's initializing:

    MyOb<int> b = a;

    So it calls the copy constructor first here.
    Last edited by dxfoo; 06-21-2010 at 11:57 PM.

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    The problem is elsewhere. Show more of the code. (the whole copy-constructor, constructor, destructor, assignment operator, member variables etc)

    However, you're also wasting time checking for NULL before doing the delete. Deleting NULL is always safe and has no effect.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    Software engineer
    Join Date
    Aug 2005
    Location
    Oregon
    Posts
    283
    Here's a short example:

    X3DData_Array2D<int> a(5, 5);
    a.Get(2, 2) = 15;
    X3DData_Array2D<int> b(a); // error here
    cout << b.Get(2, 2) << endl;

    When I set break points at each constructor it only hits the copy constructor. Because of that, the first object (b) on the left is still uninitialized with the member variables.

    Code:
    template <typename T>
    class X3DData_Array2D
    {
    private:
    	T *m_array;
    	int m_width;
    	int m_height;
    public:   
    	X3DData_Array2D(int width, int height)
    	{
    		m_array = new T[width * height];
    		m_width = width;
    		m_height = height;
    	}
    
    	X3DData_Array2D(const X3DData_Array2D &o)
    	{
    		int min_width, min_height, t1, t2;
    		T *newArray;
    
    		// Create the new array with the requested size. 
    		newArray = new T[o.m_width * o.m_height]; 
    
    		// Determine minimum size to copy over.
    		min_width = (o.m_width < m_width) ? o.m_width : m_width;
    		min_height = (o.m_height < m_height) ? o.m_height : m_height;
    
    		// Copy over data.
    		for (int y = 0; y < min_height; y++)
    		{
    			t1 = y * o.m_width;
    			t2 = y * m_width;
    
    			for (int x = 0; x < min_width; x++)
    			{
    				newArray[t1 + x] = m_array[t2 + x];
    			}
    		} 
    
    			// Delete the old array.
    		if (m_array != NULL) {
    			delete [] m_array;
    			m_array = NULL;
    		} 
    		 
    		// Store member variables.
    		m_array = newArray;
    		m_width = o.m_width;
    		m_height = o.m_height;
    	}
    	~X3DData_Array2D()
    	{
    		if (m_array != NULL)
    		{
    			delete [] m_array;
    			m_array = NULL;
    		}
    	}

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I created a copy constructor with the following code:
    It's an erroneous assumption that there is a previous state in the copy constructor. The copy constructor is called to initialize a completely new object as a copy of another.

    This means that there is no old array. Remove the entire "Release the old array" block and you'll be fine.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Software engineer
    Join Date
    Aug 2005
    Location
    Oregon
    Posts
    283
    That can't be true. The array would be initializ in this case:

    MyOb<int> a(3);
    MyOb<int> b(4);

    a = b;

  6. #6
    Software engineer
    Join Date
    Aug 2005
    Location
    Oregon
    Posts
    283
    Do you think on copy constrictor the array would be always null, and if I overrload rhe assignment operator I would delete a more probable initialized array?

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You need to provide a minimal example of how this error occurs.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by dxfoo View Post
    That can't be true.
    Yes it is. You've already seen that yourself in the debugger. You've overloaded the constructor function, it is the same as overloading any function. Only one gets called, not several or all of them. The solution is dead simple: initialize the variables in all the constructors (or, if you do not want to duplicate code, call a separate initialization function from all the constructors that contains the common details).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Software engineer
    Join Date
    Aug 2005
    Location
    Oregon
    Posts
    283
    My first example was true. With the last a = b example, the lvalue would still have allocated memory.

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by dxfoo View Post
    My first example was true. With the last a = b example, the lvalue would still have allocated memory.
    Okay, whatever. But the FACT is if you overload a function, a call to that function is a call to ONE of the alternatives, not more than one. FACT. This includes constructors.

    Do not bother trying to disprove this, or write code as if it were not true. You will just be wasting your time. The issue here is very, very simple.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Software engineer
    Join Date
    Aug 2005
    Location
    Oregon
    Posts
    283
    I'll post an example this evening.

  12. #12
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by dxfoo View Post
    I'll post an example this evening.
    An example of what? A single call to an overloaded function (such as a constructor) where more than one of the alternatives ends up firing? There is no possible example of this. Don't waste your time. The problem is solved, and the solution has been clearly explained several times by several people.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Ah yes, the problem with the copy constructor example is that m_array is not initialized.
    Your copy constructor is really a assignment operator. Initialize your members in the copy constructor first.
    Also, I have a feeling this isn't right:
    newArray[t1 + x] = m_array[t2 + x];
    I believe it should be:
    newArray[t1 + x] = o.m_array[t2 + x];
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Software engineer
    Join Date
    Aug 2005
    Location
    Oregon
    Posts
    283
    This does seem to be the case. Thanks Elysia.

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by dxfoo View Post
    That can't be true. The array would be initializ in this case:

    MyOb<int> a(3);
    MyOb<int> b(4);

    a = b;
    The last line calls the copy assignment operator, not the copy constructor. You need to define that one, too.
    Code:
    class Foo {
      Foo(Foo const &); // copy constructor, initial state of object is uninitialized!
      Foo &operator =(Foo const &); // copy assignment operator, initial state of object is some existing valid state!
    };
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamic array Allocation
    By deepak_j in forum C Programming
    Replies: 3
    Last Post: 08-17-2009, 07:18 AM
  2. Dynamic allocation for array of pointers to char
    By bivhitscar in forum C Programming
    Replies: 7
    Last Post: 05-20-2006, 07:04 AM
  3. question about multidimensional arrays
    By richdb in forum C Programming
    Replies: 22
    Last Post: 02-26-2006, 09:51 AM
  4. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  5. help with small program. array issue
    By InvariantLoop in forum C++ Programming
    Replies: 2
    Last Post: 04-09-2004, 12:26 PM