Thread: vector of vectors

  1. #1
    essence of digital xddxogm3's Avatar
    Join Date
    Sep 2003
    Posts
    589

    vector of vectors

    i'm trying to input data into a vector of vectors, but the program crashes.
    there is no compile errors, but it is obvious that my logic is not valid.
    it started to crash after i inserted the if statement.
    Code:
    #include <vector>
    #include <iostream>
    #include <fstream>
    #include <conio.h>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    { 
        vector< vector< unsigned long > > vecMemoryCache;
    
        long lgNumberOfBlocks=0;
        long lgBlocksPerSet=0;
        long lgByteAddress=0;
        long lgByteAddressConverted=0;
        long lgBlockSize=0;
        long lgAssociativity=0;
        long lgCacheSize=0;
        long lgHit=0;
        long lgMiss=0;
        unsigned long unlgTotalLoads=0;
    
        string stFileName(argv[2]);
        string stProgramName(argv[0]);
    
        if (argc != 9)
        {
            cout<<"!!Invalid Number of arguments.\nUsage: "<< argv[0] <<" -t <file_name> -s <cache_size> -b <block_size> -a <associativity>!!\n";
            exit(1);
        }
    
        ifstream inTraceFile(argv[2], ios::in);
    
        if(!inTraceFile.is_open())
        {
            cout<<"!!Unable to open file "<<argv[2]<<"!!\n";
            exit(2);
        }
    
        lgBlockSize = atoi(argv[6]);
        lgCacheSize = atoi(argv[4]);
        lgAssociativity = atoi(argv[8]);
    
        lgNumberOfBlocks = lgCacheSize/lgBlockSize;
        lgBlocksPerSet = lgNumberOfBlocks/lgAssociativity;
        
        /*
        Address Conversion
        Exact Details:
        Each line represents a byte adddress referenced by an executed load instruction. To help compress 
        the traces, instead of storing the absolute memory byte address, we store the difference from the 
        last address in the trace.
        
        I construct the Byte Address, Block  Address, and Cache Address.
        */
    
        if (lgAssociativity == 1)
        {
            while(inTraceFile>>lgByteAddress)
            {
                lgByteAddressConverted=lgByteAddressConverted+lgByteAddress;
    
                cout<<"Byte Address: "<<lgByteAddressConverted<<endl;
                cout<<"Block Address: "<<lgByteAddressConverted/lgBlockSize<<endl;
                cout<<"Cache Address: "<<(lgByteAddressConverted/lgBlockSize)%lgNumberOfBlocks<<endl;
                
                if(vecMemoryCache[0][(lgByteAddressConverted/lgBlockSize)%lgNumberOfBlocks]==lgByteAddressConverted/lgBlockSize)
                {
                    lgHit++;
                }
                else
                {
                    lgMiss++;
                    vecMemoryCache[0][(lgByteAddressConverted/lgBlockSize)%lgNumberOfBlocks]=lgByteAddressConverted/lgBlockSize;
                }
    
                unlgTotalLoads++;
    
                if(getch()==113)
                    break;
            }
        }
    
        cout<<"Program Name:    "<<stProgramName<<endl;
        cout<<"Trace File Name: "<<stFileName<<endl;
        cout<<"Cache Size:      "<<lgCacheSize<<endl;
        cout<<"Block Size:      "<<lgBlockSize<<endl;
        cout<<"Associativity:   "<<lgAssociativity <<endl;
        cout<<"Total Loads:     "<<unlgTotalLoads<<endl;
        cout<<"Total Hits:      "<<lgHit<<endl;
        cout<<"Total Misses:    "<<lgMiss<<endl;
    
        return 0;
    }
    "Hence to fight and conquer in all your battles is not supreme excellence;
    supreme excellence consists in breaking the enemy's resistance without fighting."
    Art of War Sun Tzu

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If you haven't resized the vector, it will be empty, meaning that even [0] is out of bounds.

    By the way, why do you first assume that there are at least 3 command line arguments, and only after you have used them check if the number is as expected.
    In main() you might use return 1; etc instead of exit(1).

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    For vector subscripting you can use at(), which does bounds checking, instead of [] during debugging to catch this sort of thing.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Quote Originally Posted by robatino View Post
    For vector subscripting you can use at(), which does bounds checking, instead of [] during debugging to catch this sort of thing.
    But if you don't know how to catch excetions, it would still look like a crash?

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Code:
    #include <vector>
    
    int main() {
      std::vector<int> v;
      int a = v.at(0);
    }
    When compiling with gcc 4.1.1 and running I get

    terminate called after throwing an instance of 'std::out_of_range'
    what(): vector::_M_range_check
    Aborted

  6. #6
    essence of digital xddxogm3's Avatar
    Join Date
    Sep 2003
    Posts
    589
    If you haven't resized the vector, it will be empty, meaning that even [0] is out of bounds.

    By the way, why do you first assume that there are at least 3 command line arguments, and only after you have used them check if the number is as expected.
    In main() you might use return 1; etc instead of exit(1).
    good point about testing the number of arguements.
    I will make that revision.
    So can I get an example of how you resize the vector?
    I have never used one so far.
    Can I resize it with a run time variable instead of a constant?
    "Hence to fight and conquer in all your battles is not supreme excellence;
    supreme excellence consists in breaking the enemy's resistance without fighting."
    Art of War Sun Tzu

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Vector is resized with resize() method . Yes, it can be a runtime variable.

    Another usual way of adding stuff into a vector, which doesn't require resize() is push_back().

    The error you received shows that this is indeed the problem. (I think with DevC++ you wouldn't have seen the message because it doesn't keep the console open.)

  8. #8
    essence of digital xddxogm3's Avatar
    Join Date
    Sep 2003
    Posts
    589
    i need to insert items at specific index locations.
    unfortunatly i'm unable to use it sequentially.
    that would make it a lot easier.
    i'm trying to simulate a direct mapped cache
    so if i say for instance
    Code:
    vector< vector< unsigned long > vecAssociativity > vecMemoryCache;
    
    vecAssociativity.resize(lgAssociativity);  
    vecMemoryCache.resize(lgBlocksPerSet);
    concidering the prior code, would this be valid?
    "Hence to fight and conquer in all your battles is not supreme excellence;
    supreme excellence consists in breaking the enemy's resistance without fighting."
    Art of War Sun Tzu

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Inserting something in the middle of a vector is very inefficient. May-be try std::map?

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    It's not that inefficient speed-wise if you are using resize (as is the case here), but it can be inefficient space-wise. If the population of the vector will be sparse, then a map (or unordered_map) would be better, otherwise I would still use vector.

  11. #11
    essence of digital xddxogm3's Avatar
    Join Date
    Sep 2003
    Posts
    589
    Another question about a vector of vectors.
    How would I erase a location in a vector?
    Below is what I tried, but it doesn't work.
    How would I do this?
    Code:
    for(int x =1;x< lgNumberOfBlocks; x++)
    {
         if (vecLRU[1][x]==lgByteAddressConverted)
         {
               vecLRU[1][x].erase();
         }
    }
    "Hence to fight and conquer in all your battles is not supreme excellence;
    supreme excellence consists in breaking the enemy's resistance without fighting."
    Art of War Sun Tzu

  12. #12
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I think:
    Code:
    vecLRU[1].erase(vecLRU[1].begin() + x);
    But make sure not to increment x at that point or you will skip over an element in the vector.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Vectors
    By naseerhaider in forum C++ Programming
    Replies: 11
    Last Post: 05-09-2008, 08:21 AM
  2. How can i made vectors measuring program in DevC++
    By flame82 in forum C Programming
    Replies: 1
    Last Post: 05-07-2008, 02:05 PM
  3. How properly get data out of vectors of templates?
    By 6tr6tr in forum C++ Programming
    Replies: 4
    Last Post: 04-15-2008, 10:35 AM
  4. How to use Vector's in C++ !?!
    By IndioDoido in forum C++ Programming
    Replies: 3
    Last Post: 10-14-2007, 11:13 AM
  5. Points, vectors, matrices
    By subnet_rx in forum Game Programming
    Replies: 17
    Last Post: 01-11-2002, 02:29 PM