Problem in large memory allocating

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • arashmath
    New Member
    • May 2008
    • 6

    Problem in large memory allocating

    Hi everyone,

    I have a problem with large dynamic memory allocating. this is my code (in briefness):

    Code:
    #include <stdio.h>
    #include <mem.h>
    #include <assert.h>
    #define SML_BOUNDS_CHECK
    
    class Vector_d
    {
       private:
          int Dim_;
          double* Val_;
       public:
          Vector_d() { Dim_ = 0; Val_ = NULL; }
          ~Vector_d() { delete[] Val_; }
          int SetDim( int N ); // Get memory for Val_
    };
    
    class SVector_d
    {
       private:
          int NNZ_;
          double* Val_;
          int* Ind_;
       public:
          SVector_d() { Val_ = NULL;	Ind_ = NULL; NNZ_ = 0; };
          ~SVector_d() { delete[] Val_; delete[] Ind_; };
          int SetNNZ( int NNZ ); // Get memory for Val_ and Ind_
          int& Index( int NZI );
          double& Value( int NZI );
          SVector_d& operator=( const SVector_d& V );
          friend class SMatrix_d;
    };
    
    class SMatrix_d
    {
       private:
          int NVec_;
          SVector_d* Vec_;
       public:
          SMatrix_d() { NVec_ = 0; Vec_ = NULL; };
          ~SMatrix_d() {	delete[] Vec_; };
          int SetNVec( int NV );
          SVector_d& operator()( int Index );
    };
    
    int Vector_d::SetDim( int N )
    {
       if(N==Dim_) return 0;
       delete[] Val_;
       Val_ = new double[N];
       Dim_ = N;
       return 0;
    }
    
    int SVector_d::SetNNZ( int NNZ )
    {
       if(NNZ==NNZ_) return 0;
       delete[] Val_;
       Val_ = new double[NNZ];
       delete[] Ind_;
       Ind_ = new int[NNZ];
       NNZ_ = NNZ;
       return 0;
    }
    
    int& SVector_d::Index( int NZI )
    {
       #ifdef SML_BOUNDS_CHECK
          assert( 0<=NZI && NZI<NNZ_ );
       #endif
       return Ind_[NZI];
    }
    
    double& SVector_d::Value( int NZI )
    {
       #ifdef SML_BOUNDS_CHECK
          assert( 0<=NZI && NZI<NNZ_ );
       #endif
       return Val_[NZI];
    }
    
    SVector_d& SVector_d::operator=( const SVector_d& V )
    {
       if (this == & V) return *this;
       SetNNZ( V.NNZ_ );
       memcpy( Val_ , V.Val_ , sizeof(double)*NNZ_ );
       memcpy( Ind_ , V.Ind_ , sizeof(int)*NNZ_ );
       return *this; // General call
    }
    
    int SMatrix_d::SetNVec( int NV )
    {
       if(NV==NVec_) return 0;
       delete[] Vec_;
       Vec_ = new SVector_d[NV];
       NVec_ = NV;
       return 0;
    }
    
    SVector_d& SMatrix_d::operator()( int Index )
    {
       #ifdef SML_BOUNDS_CHECK
          assert( 0<=Index && Index<NVec_ );
       #endif
       return Vec_[Index];
    }
    
    int main() {
       int Adim = 7000000;
       int udim = 1000000;
       printf("A dimension = %d\n",Adim);
       printf("u dimension = %d\n",udim);
       Vector_d u;
       u.SetDim( udim );
       SMatrix_d A;
       A.SetNVec( Adim );
       SVector_d SV;
       SV.SetNNZ(5);
       for(int i=0; i<5; i++) { SV.Value(i) = i; SV.Index(i)=i; };
       for(int i=0; i<Adim; i++ )	A(i) = SV;
       A.SetNVec( 20 ); // Error occurs at this place
       A(0) = SV;
       printf("Done!\n");
       return 0;
    } // End of program
    The runtime error occurs when program releases memory that is allocated to "Vec_".
    This program gets 1GB of memory approximately, while the 32bits systems can use at most 4GB of memory.
    if I reduce the value of "Adim" or "udim", program will get less memory, and there will be no error.
    However I need to set these large values to both "Adim" and "udim".
    My compliler is Borland C++ 5.02.
    I will appreciate, if you help me to overcome this problem.

    Thanks.
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    If is not clear to me why you have chose to implement you own vectors ignoring the STL <vector> class, additionally you seem to be using a compiler that is 8at least 8 years old, you may wish to use a newer one.

    Finally you have not said what error you are getting you have just alluded to some mysterious error without every mentioning it.

    However I believe you problem is that you have not implemented any copy constructors or assignment operators. In this case the compiler creates them for you and it does a member to member copy and that means that at line 119 of your code all the vectors in your matrix end up sharing the same allocated memory buffer and so when they are deleted in the call to SetNVec at line 120 after the first vector in the array the destructor is trying to delete memory blocks that are no longer valid.

    So I would guess you are getting invalid memory block exceptions during the delete.

    Comment

    • gpraghuram
      Recognized Expert Top Contributor
      • Mar 2007
      • 1275

      #3
      Try running the same with Rational Purify to find if there are are any memory corruption..... .
      That may help u to identify the issue.

      raghu

      Comment

      • arashmath
        New Member
        • May 2008
        • 6

        #4
        I have made the code much simpler:

        Code:
        class SVector_d
        {
           private:
              double* V_;
           public:
              SVector_d() { V_ = 0; }; // Set V_ to NULL
              ~SVector_d() { delete[] V_; };
              void SetSize(int N) { delete[] V_; V_ = new double[N]; }
        };
        
        int main() {
           double* DPtr = new double[524281];
           int SZ = 50000;
        	SVector_d* SVPtr = new SVector_d[SZ];
           for(int i=0; i<SZ; i++) SVPtr[i].SetSize(1000);
           delete[] SVPtr; // Error: Fault access violation...
           delete[] DPtr;
           return 0;
        }
        This code makes the same runtime error "Fault: access violation..." when the program frees memory allocated to "SVPtr" (at line 16).
        What do i have to do to get out of this problem?
        Declaring copy constuctor in class "SVector_d" does not help any more.
        I reminde again that the program will run without any problem if i reduce dynamic memoy size. (Instance line 12 should be replaced by "double* DPtr = new double[500000];")

        Thanks.

        Comment

        • Savage
          Recognized Expert Top Contributor
          • Feb 2007
          • 1759

          #5
          I don't get any access violation when I run this code nor on VC++ 2005 or Borland
          C++ Builder 5. Try wrapping the allocation code inside try-catch block to see if any error happened during the allocation.

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            I agree with Savage, that 2nd set of code appears to be fine nothing wrong with it. It also runs for me in VS 2005 Express. It only failed when I set SZ high enough to cause the system to run out of virtual address space (About 2GB).

            So my guess is that you are running into a limit of your platform (your platform being the compiler/OS combination you are using).

            Also I was wrong wasn't I, your compiler is not 8 years old, that is C++ Builder 5, you compiler is 11 years old, and there appears to be anecdotal evidence that it is a 16bit compiler.

            I seriously suggest you get something a little more modern, may be something released this century.

            Your other options are

            1. Try to work out what it is about your platform that is causing the error and find a work-around. Although I suspect it is hitting some hard-coded/hard-wired limit.

            2. You could used memory mapped files, that is rather than trying to hold all your data in memory use a file to hold it and only load in part of it to operate on at a time. If you are able to use the WIN32 API then there are functions provided to enable you to do this fairly easily, look up MapViewOfFile on MSDN. Of course if your compiler is 16bit this may not be an option you may have to write the whole thing yourself.

            Comment

            • arashmath
              New Member
              • May 2008
              • 6

              #7
              You are right. I must get a new version of compiler. That is my answer. Thanks.

              Comment

              Working...