Solved

trouble with new

Posted on 1998-06-24
30
226 Views
Last Modified: 2010-04-01
in my array template class of type 'T' I have the following line:

T * TempTArray = new T[TempTLength];

I have used the debugger to pinpoint this line as the trouble.  It goes to the new operator code to allocate memory, and somewhere in the middle of it I get the following error:

"unhandled exception in arraytest.exe:0xC000005: Access Violation"

and sends me to KERNEL32!bff782af( ) with the yellow arrow that says which line the error occured in pointing at the line, in assembly:

mov    pword ptr[ecx + 08], eax

Please tell me what is going on!
0
Comment
Question by:Booth882
  • 13
  • 12
  • 2
  • +3
30 Comments
 

Expert Comment

by:t004024
ID: 1166610
Do U have code in U'r constructor for class T, it maybe giving access violation in the constructor.
0
 
LVL 8

Expert Comment

by:trestan
ID: 1166611
Please email me the whole code to find the reason. You can find my email address from my homepage.

0
 
LVL 22

Expert Comment

by:nietod
ID: 1166612
Why don't you post the code for the class's default constructor here.  We only need to see the default constructor (not any others), and any functions it calls.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166613
here is the array class in its entireity

#ifndef __array_h
#define __array_h

template <class T>
class array
{
private:
      T * TheArray;
      int TheLength;
public:
      array(int InitialLength);
      ~array();

      array & operator=(array & ArrayReference);
      T & operator[](int Offset);
      
      int GetTheLength(){return TheLength;};
      T * GetTheArray(){return TheArray;};
      void GrowTheArray(int AmountOfGrowth);
      void ShrinkTheArray(int AmountOfShrank);
      void AddToArray(T & TReference);
};

template <class T>
array<T>::array(int InitialLength)
{
      TheLength = InitialLength;
      TheArray = new T[TheLength];
      for(int hon = 0; hon < TheLength; hon++)
            TheArray[hon] = 0;
}

template <class T>
array<T>::~array()
{
      delete [] TheArray;
      TheArray = 0;
}

template <class T>
array<T> & array<T>::operator=(array<T> & ArrayReference)
{
      int TheDifference = (ArrayReference.GetTheLength() - TheLength);
      if(TheDifference > 0)
      {
            GrowTheArray(TheDifference);
            TheLength = ArrayReference.GetTheLength();
      }
      if(TheDifference < 0)
      {
            ShrinkTheArray(0 - TheDifference);
            TheLength = ArrayReference.GetTheLength();
      }
      
      for(int Pount = 0; Pount < TheLength; Pount++)
            TheArray[Pount] = ArrayReference[Pount];
      
      return *this;
}

template <class T>
T & array<T>::operator[](int Offset)
{
      return TheArray[Offset];
}

template <class T>
void array<T>::GrowTheArray(int GrowthAmount)
{
      int TempLength = TheLength + GrowthAmount;
      T * TempT = new T[TempLength];

      for(int i = 0; i < TheLength; i++)
            TempT[i] = TheArray[i];
      for(int u = TheLength; u < TempLength; u++)
            TempT[u] = 0;

      delete [] TheArray;
      TheArray = TempT;
      TheLength = TempLength;
}

template <class T>
void array<T>::ShrinkTheArray(int AmountOfShrank)
{
      int TempLength = TheLength - AmountOfShrank;
      if(TempLength < 1)
            return;
      T * TempT = new T[TempLength];

      for(int h = 0; h < TempLength; h++)
            TempT[h] = TheArray[h];

      delete TheArray;
      TheArray = TempT;
      TheLength = TempLength;
}

template<class T>
void array<T>::AddToArray(T & TReference)
{
      GrowTheArray(1);
      TheArray[TheLength - 1] = TReference;
}

#endif

hope this helps!
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166614
the trouble is in the GrowTheArray function when I declare TempT to be a new T[TempLength].
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166615
answer coming.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166616
Opps.  I'm wrong.  I thought I saw a mistake.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166617
If growamount was negative the function would crash.  Are you sure that is not the case?  You could put in an assert to make sure.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166618
Not related to the problem, but inside the operator = function, you sent the array length after calling GrowTheArray and ShrinkTheArray() that is not needed.  These functions change the array length.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166619
Another unrelated problem, Inside shrinkthearray you have "delete TheArray;" it should be "delete [] TheArray;".
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166620
What type are you instanciating the template for?  I suspect this type has a problem in its constructor.  Can you create the template using a simple type like "int".  "int" has no constructors.  if the problem goes away with "int", but is there with a type that has constructors, I would look at the constructor for the type you are using.

Sorry to have locked this up.  I missread the two loops in the grow function and thought it was a mess.  It actually looks pretty good.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166621
no sweat.  I'll check out your comments and be back
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166622
it doesnt work for an int or an array<int>.  I have tried them both.  The array<int> takes a value for it's constructor.  how would I phrase that?

typedef array<int> IntArray;

array<IntArray>  BigArray(2);

T * TempT = new array<T>(2)[10];

or

T * TempT = new array<T>[10](2);

where 2 is the parameter passed to the constructor and 10 is the size of the array.  How do I do that? it may be what's wrong.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166623
i fixed the others.  thanks
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166624
that cant be the only problem though.  when I say:

array<int> TheArray(4);
array<int> TheOtherArray(6);

TheArray = TheOtherArray;

it gives me the same error.  the problem is in the new operator in GrowTheArray function called by the equals operator in this line:

T * TempT = new T [ TempLength ];

something goes wrong with the allocation.  I just dont know what it is.
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 22

Expert Comment

by:nietod
ID: 1166625
Is

array<int> TheArray(4);
array<int> TheOtherArray(6);

TheArray = TheOtherArray;

the only think in the program?  i.e.  is that all that is in main?  When I create a program that just does that in main, it runs fine.  If your program is doing other things, you may have a problem elsewhere that is corrupting the heap and causing "new" to fail.  Can you reproduce the error in a program that does nothing but the above?
0
 
LVL 11

Expert Comment

by:alexo
ID: 1166626
void main()
{
    array<int> TheArray(4);
    array<int> TheOtherArray(6);
    TheArray = TheOtherArray;
}

Ran perfectly for me.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166627
really? wow, I'll check that out
0
 
LVL 3

Expert Comment

by:danny_pav
ID: 1166628
why not just use the vector out of the STL?
0
 
LVL 11

Expert Comment

by:alexo
ID: 1166629
Maybe because it's a homework assignment?
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166630
its not a homework assignment.  I like to use all my own classes, just because I know how they work intimately and can change them at will.  I would redo iostream and conio if only I knew how!
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166631
you guys are right.  it works fine just like that.  here is a copy of my arraytest.cpp:

#include <iostream.h>
#include <conio.h>
#include <array.h>

typedef array<int> IntArray;

void Display(array<int> & TheArray)
{
for(int k = 0; k < TheArray.GetTheLength(); k++)
cout << TheArray[k] << " ";

getch();
}

void main()
{
array<int> AnArray(4);
array<int> OtherArray(6);
      
cout << "initializing AnArray" << endl;
for(int y = 1; y < 5; y++)
{
AnArray[y] = y;
cout << AnArray[y] << " ";
}
cout << endl;
getch();

cout << "initializing OtherArray" << endl;
for(int u = 8; u < 19; u += 2)
{
OtherArray[u] = u;
cout << OtherArray[u] << " ";
}
cout << endl;
getch();

cout << "administering equals test" << endl;
AnArray = OtherArray;
Display(AnArray);

cout << "calling AddToArray" << endl;
int TheInt = 88;
AnArray.AddToArray(TheInt);
Display(AnArray);
      
cout << "calling ShrinkTheArray" << endl;
AnArray.ShrinkTheArray(3);
Display(AnArray);
}


the problem is in the equals test when I say:

AnArray = OtherArray;

but when I comment out the initialization loops for AnArray and OtherArray at the beginning of main() it works just fine.  so setting the individual elements of the array to something corrupts the new operator in GrowTheArray?  I dont understand.  please tell me what you think
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166632
>> I like to use all my own classes

Very, very very stupid idea.  By the way,  I do it that way myself (Including the streams.)  Like you I want to know how they work internatlly, and I want them to work the way I want them to work.  But it probably is a bad idea al the same.

Does the problem reproduce in a simple program?  If not, you've got a corrupted heap.  In this case, there are ways to track down the source of the problem.  But it usually is a pain.  If you are using VC, it can help.  Another possibility is boundschecker.


0
 
LVL 22

Expert Comment

by:nietod
ID: 1166633
I ran this under VC an it detected a corrupted heap.  I'll look a little closer.
0
 
LVL 22

Accepted Solution

by:
nietod earned 110 total points
ID: 1166634
I see the problem.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166635
to each his own, I guess.  it's just the way I like to do it.

corrupted heap? what does that mean?
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166636
The problem is you are using invalid indexes into the arrays.  You define "AnArray to have 4 elements, those are number from 0 to 3, but you initialize from 1 to 4. in the loop

for(int y = 1; y < 5; y++)
     {
     AnArray[y] = y;
     cout << AnArray[y] << " ";
     }

If you did

for(int y = 0; y < 4; y++)
     {
     AnArray[y] = y;
     cout << AnArray[y] << " ";
     }

you would be fine (until the next loop that does the same sort of thing.)

Now I'm wondering.  Are you trying to make your arrays numbered from one instead of from 0?  You can do that by having the code inside the operator [] procedure subtract one from the index.

In any case you might want to do an error check for invalid indexes (and other problems) in the class.  You can use conditional compilation to make sure the code is removed in the final version.  You will save yourself a lot of agrivation that way.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1166637
These comments are getting all out of order.  The heap is the memory pool (or pools) that the memory returned from new and malloc comes from.  It is gigantic data stucture with sections that are in use by your program (allocated by malloc or new) and sections that are free, in addition it has informaiton for managing this huge structure  (basically a linked list).  If you write past one of the ends of a block taken from the heap you will be causing problems.  if you are lucky you will just write over another block that is free.  Or you might over a block that you are using and cause a very weird error that shows up later.  However, what you were doing in this case, was writing over data used to manage the heap.  Thus when the run-time library when to search the heap for more free memory it died.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166638
Ahh, so simple.  I wanted the values to be from one to four, but the indexes from zero to three.  stupid mistake.  thanks I'll check it out and see if it works.
0
 
LVL 1

Author Comment

by:Booth882
ID: 1166639
thanks nietod you have once again saved the day.  
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now