Thread: vector wierdity

  1. #1
    Registered User
    Join Date
    Aug 2005
    Posts
    128

    vector weirdity

    I'm reading a comma-delimited file into a struct-based vector
    Then I process the vector contents (validations, etc.)
    At the end, I write out the new vector contents.

    All of this works...wait for it...except...about 5 records into a 300K record file, two records are not seen by the validation at all but are written out to the file at the end.

    Where could my vector records be hiding?

    Here is the validation
    Code:
    int main()
    {
    
    //define sitetype to hold return value
    	int rval = 0;
    
    	nsSVector::csVector SV;
    	SV.initialize_vector(schoolvector);
    	std::cout << "initialized.";
    
    	//process
    	nsValidation::csValidation VD;
    	
    	std::vector<nsSVector::record*>::iterator start = schoolvector.begin();
    	std::vector<nsSVector::record*>::iterator stop = schoolvector.end();
    
    	for( ; start != stop; ++start)
    	{
    		//std::cout << (*start)->lastname <<std::endl;
    		if (VD.validateCorp((*start)->corp) == 0)
    		{
    			VD.validateNames("LAST",(*start)->lastname);
    			VD.validateNames("FIRST",(*start)->firstname);
    			VD.validateLWI((*start)->lwi);
    			VD.validateGrade((*start)->grade);
    			VD.validateTANF((*start)->tanf);
    			VD.validateSSN((*start)->ssn);
    		}
    		else
    		{
    			schoolvector.erase(start);
    		}
    	}
    
    
    
    	SV.build_new_file(schoolvector);
    	std::cout<<  "built";
    	//remove vector
    	SV.cleanup_SV_vector(schoolvector);
    
    	return 0;
    }
    Here is the file write
    Code:
    int build_new_file(std::vector<record*>& vec)
    		{
    			//REBUILD FILE BASED ON VECTOR CONTENTS
    			std::ofstream a_file ( "out.csv", std::ios::trunc );
    			//test file
    			if ( !a_file.is_open() ) {
    				return 0;
    			}
    			else 
    			{
    				std::vector<record*>::iterator start = vec.begin();
    				std::vector<record*>::iterator stop = vec.end();
    				for( ; start != stop; ++start)
    				{
    					a_file << (*start)->corp << "," << (*start)->lastname << "," 
    << (*start)->firstname << "," << (*start)->lwi << "," 
    << (*start)->grade << "," << (*start)->tanf 
    
    << "," << (*start)->ssn << std::endl;
    				}
    				a_file.close();
    				return 1;
    			}
    		}
    Last edited by FoodDude; 09-27-2005 at 01:42 PM.

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You are not erasing from the vector correctly. The erase method returns the next valid iterator, and so you should use that instead of letting the for loop call ++start to increment the iterator that got deleted. Once you call erase with an iterator, that iterator is invalidated, and so it is entirely possible that when you increment it, it skips one or more existing locations. It could also cause a crash under certain circumstances.

    An easy solution is to use a while loop (e.g. while (start != stop)) and increment start if you don't erase it- at the end of the if block. Inside the else block, you would assign it to the return value of erase:
    Code:
      // ...
      ++start;
    }
    else
    {
      start = schoolvector.erase(start);
    }

  3. #3
    Registered User
    Join Date
    Aug 2005
    Posts
    128
    Thanks again. Your responses are so informative and helpful.

Popular pages Recent additions subscribe to a feed