Click here to Skip to main content
15,886,963 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
SQL
Unhandled exception at 0x76acfbae in AC.exe: Microsoft C++ exception: std::out_of_range at memory location 0x0015a140.. "


Any advice on how to handle this error?


I checked the memory , the program use almost 1GB of the memory of 2GB RAM....So its not the memory.....
CSuffixTrie.h
<pre>#if !defined(AFX_SUFFIXTRIE_H__34D2D872_1C59_4D9F_BAF1_6AB80D7333B1__INCLUDED_)
#define AFX_SUFFIXTRIE_H__34D2D872_1C59_4D9F_BAF1_6AB80D7333B1__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#pragma warning(disable:4786)
#include <map>
#include <string>
#include <vector>
#include <set>
class CSuffixTrie 
{
public:
	//Our string type
	typedef std::wstring SearchString;
	//Data returned from our search
	typedef struct _DataFound
	{
		int				iFoundPosition;
		SearchString	sDataFound;
	} DataFound;
	//Our vector of data found
	typedef std::vector<datafound> DataFoundVector;
	//All the strings vector
	typedef std::vector<searchstring> StringsVector;
	//All the strings set
	typedef std::set<searchstring> StringsSet;
public:
	//Get all the strings in the tree
	//Vector format
	StringsVector GetAllStringsVector()const;
	//Set format
	StringsSet GetAllStringsSet()const;
	//Clear the trie
	void Clear();
	//Build the tree index for Aho-Corasick
	//This is done when all the strings has been added
	void BuildTreeIndex();
	//Add a string (will destroy normalization, caller is reponsible for this part)
	void AddString(const SearchString&amp; rString);
	//Get string (is the string there?)
	bool FindString(const SearchString&amp; rString)const;
	//Delete a string (will destroy normalization, caller is reponsible for this part)
	void DeleteString(const SearchString&amp; rString);
	//Do an actual find for the first match
	DataFound SearchAhoCorasik(const SearchString&amp; rString)const;
	//Do an actual find for all the matches
	DataFoundVector SearchAhoCorasikMultiple(const SearchString&amp; rString)const;
	//Assigmnet operator
	CSuffixTrie&amp; operator=(const CSuffixTrie&amp; rTrie);
	//Ctor and Dtor
	CSuffixTrie();
	CSuffixTrie(const CSuffixTrie&amp; rTrie);
	virtual ~CSuffixTrie();
private:
	//Our char search type
	typedef wchar_t SearchChar;
	//Forward declare the node
	struct _Node;
	//Our map
	typedef std::map &lt;SearchChar,_Node*&gt; SearchMap;
	//Our node
	typedef struct _Node
	{
		SearchChar		aChar;	//Our character
		bool			bFinal; //Do we have a word here
		SearchMap		aMap;	//Our next nodes
		_Node*			pFailureNode;	//Where we go incase of failure
		unsigned short	usDepth;	//Depth of this level
	} Node;
private:
	//Add a string to a node
	void AddString(const SearchString&amp; rString,
				   Node* pNode);
	//Search for a non final string (this is to build the index)
	//If not found then it will get the root node
	const Node* SearchNode(const SearchString&amp; rString,
						   const Node* pNode)const;
	Node* SearchNode(const SearchString&amp; rString,
					 Node* pNode);
	//Build the node index
	void BuildIndex(const SearchString&amp; rString,
					Node* pNode);
	//Delete a node
	void DeleteNode(Node* pNode)const;
	//Clone a node
	Node* CloneNode(const Node* pNode)const;
	//Clone the entire trie
	void CloneTrie(CSuffixTrie&amp; rTarget)const;
	//Insert a string into a vector
	void BuildStrings(StringsVector&amp; rVector,
				      const SearchString&amp; rString,
					  const Node* pNode)const;
	//Our root node
	Node m_aRoot;
};
#endif // !defined(AFX_SUFFIXTRIE_H__34D2D872_1C59_4D9F_BAF1_6AB80D7333B1__INCLUDED_)
</searchstring></searchstring></datafound></set></vector></string>


CSuffixTrie.cpp

#include "stdafx.h"
#include "SuffixTrie.h"
CSuffixTrie::CSuffixTrie()
{
	//Init the root node
	m_aRoot.pFailureNode=NULL;
	m_aRoot.aChar=0;
	m_aRoot.bFinal=false;
	m_aRoot.usDepth=0;
}
CSuffixTrie::CSuffixTrie(const CSuffixTrie&amp; rTrie)
{
	//Clone to here
	rTrie.CloneTrie(*this);
}
CSuffixTrie::~CSuffixTrie()
{
	//Delete the tree
	Clear();
}
void CSuffixTrie::Clear()
{
	DeleteNode(&amp;m_aRoot);
}
CSuffixTrie&amp; CSuffixTrie::operator=(const CSuffixTrie&amp; rTrie)
{
	//Sanity check
	if (this==&amp;rTrie)
		return *this;
	//Close ourselves first
	rTrie.CloneTrie(*this);
	//Done
	return *this;
}
void CSuffixTrie::CloneTrie(CSuffixTrie&amp; rTarget)const
{
	//First delete the other trie
	rTarget.Clear();
	//Do a clone
	Node* pClone;
	pClone=CloneNode(&amp;m_aRoot);
	//Save it
	rTarget.m_aRoot=*pClone;
	//Renormalize it
	rTarget.BuildTreeIndex();
	//And delete that node
	delete pClone;
}
void CSuffixTrie::AddString(const SearchString&amp; rString)
{
	//Add the string
	AddString(rString,
			  &amp;m_aRoot);
}
void CSuffixTrie::AddString(const SearchString&amp; rString,
						    Node* pNode)
{
	//Sanity check
	if (!pNode ||
		rString.empty())
		return;
	//The char we are looking for
	SearchChar aChar;
	aChar=rString[0];
	//Look for the next node
	SearchMap::iterator aIterator;
	aIterator=pNode-&gt;aMap.find(aChar);
	//Our node
	Node* pNewNode;
	//Do we have it?
	if (aIterator==pNode-&gt;aMap.end())
	{
		//Need to build this node
		pNewNode=new Node;
		//Reset it
		pNewNode->pFailureNode=NULL;
		pNewNode->aChar=aChar;
		pNewNode->usDepth=pNode-&gt;usDepth+1;
		pNewNode->bFinal=false;
		//Add it
		pNode->aMap.insert(SearchMap::value_type(aChar,pNewNode));
	}
	else
		//Take the node
		pNewNode=aIterator->second;
	//Is it the last char?
	if (rString.length()==1)
		//Set as last
		pNewNode->bFinal=true;
	else
		//Run next layer
		AddString(rString.substr(1,rString.length()-1),
				  pNewNode);
}
void CSuffixTrie::DeleteNode(Node* pNode)const
{
	//Make sure we have it
	if (!pNode)
		return;
	//Iterate all its children
	for (SearchMap::iterator aIterator=pNode->aMap.begin();
		 aIterator!=pNode->aMap.end();
		 ++aIterator)
	{
		//Send it to deletion
		DeleteNode(aIterator->second);
		//We can assume all the children have been deleted, then delete it
		delete aIterator->second;
	}
}
void CSuffixTrie::BuildTreeIndex()
{
	//Build index on the root
	BuildIndex(L"",
			   &m_aRoot);
}
CSuffixTrie::Node* CSuffixTrie::SearchNode(const SearchString&amp; rString,
										   Node* pNode)
{
	//Sanity check
	if (!pNode ||
		rString.empty())
		return NULL;
	//The char we are looking for
	SearchChar aChar;
	aChar=rString[0];
	//Look for the next node
	SearchMap::iterator aIterator;
	aIterator=pNode->aMap.find(aChar);
	//Do we have it?
	if (aIterator!=pNode->aMap.end())
	{
		//Is it the last char?
		if (rString.length()==1)
			//We found our string
			return aIterator->second;
		else
			//Search again
			return SearchNode(rString.substr(1,rString.length()-1),
							  aIterator->second);
	}
	else
		//Not found
		return NULL;
}
const CSuffixTrie::Node* CSuffixTrie::SearchNode(const SearchString& rString,
												 const Node* pNode)const
{
	//Sanity check
	if (!pNode ||
		rString.empty())
		return NULL;
	//The char we are looking for
	SearchChar aChar;
	aChar=rString[0];
	//Look for the next node
	SearchMap::const_iterator aIterator;
	aIterator=pNode->aMap.find(aChar);
	//Do we have it?
	if (aIterator!=pNode->aMap.end())
	{
		//Is it the last char?
		if (rString.length()==1)
			//We found our string
			return aIterator->second;
		else
			//Search again
			return SearchNode(rString.substr(1,rString.length()-1),
							  aIterator->second);
	}
	else
		//Not found
		return NULL;
}
void CSuffixTrie::BuildIndex(const SearchString& rString,
							 Node* pNode)
{
	//Sanity
	if (!pNode)
		return;
	//Do we need to process this node?
	if (pNode->usDepth&gt;1)
	{
		//Clear the node first
		pNode-&gt;pFailureNode=NULL;
		//We need to start and look for suffix/prefix
		for (int iCount=1;
			 iCount&lt;rString.length();
			 ++iCount)
		{
			//Build the sub string
			SearchString sString;
			sString=rString.substr(iCount,rString.length()-iCount);
			//And search
			Node* pFoundNode;
			pFoundNode=SearchNode(sString,
								  &amp;m_aRoot);
			//Did we get it?
			if (pFoundNode)
			{
				//Save it
				pNode->pFailureNode=pFoundNode;
				//Exit from this loop
				break;
			}
		}	
	}
	//Build the next string
	SearchString sString(rString);
	//Iterate all its children
	for (SearchMap::iterator aIterator=pNode->aMap.begin();
		 aIterator!=pNode->aMap.end();
		 ++aIterator)
		//Build the index
		BuildIndex(rString+aIterator->first,
				   aIterator->second);
}
CSuffixTrie::DataFound CSuffixTrie::SearchAhoCorasik(const SearchString& rString)const
{
	//Our data found
	DataFound aData;
	aData.iFoundPosition=0;
	//The current string we match
	SearchString sMatchedString;
	//Our node position
	const Node* pNode;
	pNode=&m_aRoot;
	//Iterate the string
	for (int iCount=0;
		 iCount<rstring.length();>
		 ++iCount)
	{
		//Did we switch node already
		bool bSwitch;
		bSwitch=false;
		//Loop while we got something
		while (1)
		{
			//Look for the char
			SearchMap::const_iterator aIterator;
			aIterator=pNode->aMap.find(rString[iCount]);
			//Do we have it?
			if (aIterator==pNode->aMap.end())
				//No, check if we have failure node
				if (!pNode->pFailureNode)
				{
					//No failure node, start at root again
					pNode=&m_aRoot;
					//Reset search string
					sMatchedString=L"";
					//Did we do a switch?
					if (bSwitch)
						//We need to do this over
						--iCount;
					//Exit this loop
					break;
				}
				else
				{
					//What is the depth difference?
					unsigned short usDepth;
					usDepth=pNode->usDepth-pNode->pFailureNode->usDepth-1;
					//This is how many chars to remove
					sMatchedString=sMatchedString.substr(usDepth,sMatchedString.length()-usDepth);
					//Go to the failure node
					pNode=pNode->pFailureNode;
					//Set to switch
					bSwitch=true;
				}
			else
			{
				//Add the char
				sMatchedString+=rString[iCount];
				//Save the new node
				pNode=aIterator->second;
				//Exit the loop
				break;
			}
		}
		//Is this a final node?
		if (pNode->bFinal)
		{
			//We got our data
			aData.iFoundPosition=iCount-sMatchedString.length()+1;
			aData.sDataFound=sMatchedString;
			//Exit
			return aData;
		}
	}
	//Nothing found
	return aData;
}
CSuffixTrie::DataFoundVector CSuffixTrie::SearchAhoCorasikMultiple(const SearchString& rString)const
{
	//Our vector of data found
	DataFoundVector aVec;
	//The current string we match
	SearchString sMatchedString;
	//Our node position
	const Node* pNode;
	pNode=&m_aRoot;
	//Iterate the string
	for (int iCount=0;
		 iCount < rString.length();
		 ++iCount)
	{
		//Did we switch node already
		bool bSwitch;
		bSwitch=false;
		//Loop while we got something
		while (1)
		{
			//Look for the char
			SearchMap::const_iterator aIterator;
			aIterator=pNode->aMap.find(rString[iCount]);
			//Do we have it?
			if (aIterator==pNode->aMap.end())
				//No, check if we have failure node
				if (!pNode->pFailureNode)
				{
					//No failure node, start at root again
					pNode=&m_aRoot;
					//Reset search string
					sMatchedString=L"";
					//Did we do a switch?
					if (bSwitch)
						//We need to do this over
						--iCount;
					//Exit this loop
					break;
				}
				else
				{
					//What is the depth difference?
					unsigned short usDepth;
					usDepth=pNode->usDepth-pNode->pFailureNode->usDepth-1;
					//This is how many chars to remove
					sMatchedString=sMatchedString.substr(usDepth,sMatchedString.length()-usDepth);
					//Go to the failure node
					pNode=pNode->pFailureNode;
					//Set to switch
					bSwitch=true;
				}
			else
			{
				//Add the char
				sMatchedString+=rString[iCount];
				//Save the new node
				pNode=aIterator->second;
				//Exit the loop
				break;
			}
		}
		//Is this a final node?
		if (pNode->bFinal)
		{
			//We got our data
			DataFound aData;
			aData.iFoundPosition=iCount-sMatchedString.length()+1;
			aData.sDataFound=sMatchedString;
			//Insert it
			aVec.push_back(aData);
			//Go back
			iCount-=sMatchedString.length()-1;
			//Reset the data
			sMatchedString=L"";
		}
	}
	//Done
	return aVec;
}
CSuffixTrie::Node* CSuffixTrie::CloneNode(const Node* pNode)const
{
	//Sanity check
	if (!pNode)
		return NULL;
	//Create the new node
	Node* pNewNode;
	pNewNode=new Node;
	//Copy the data
	pNewNode->aChar=pNode->aChar;
	pNewNode->bFinal=pNode->bFinal;
	pNewNode->pFailureNode=NULL;
	pNewNode->usDepth=pNode->usDepth;
	//Now clone the sub nodes
	for (SearchMap::const_iterator aIterator=pNode->aMap.begin();
		 aIterator!=pNode->aMap.end();
		 ++aIterator)
	{
		//Clone this sub node
		Node* pSubNode;
		pSubNode=CloneNode(aIterator->second);
		//Did we get it?
		if (pSubNode)
			//Insert it
			pNewNode-&gt;aMap.insert(SearchMap::value_type(aIterator->first,pSubNode));
	}
	//Done
	return pNewNode;
}
bool CSuffixTrie::FindString(const SearchString& rString)const
{
	return SearchNode(rString,
					  &m_aRoot)!=NULL;
}
CSuffixTrie::StringsVector CSuffixTrie::GetAllStringsVector()const
{
	//Our vector
	StringsVector aVector;
	//Start to build the trie
	BuildStrings(aVector,
				 L"",
				 &m_aRoot);
	//Done
	return aVector;
}
CSuffixTrie::StringsSet CSuffixTrie::GetAllStringsSet()const
{
	//We will convert the vector
	StringsVector aVector(GetAllStringsVector());
	//Our set
	StringsSet aSet;
	//Iterate it
	for (int iCount=0;
		 iCount < aVector.size();
		 ++iCount)
		//Insert to the set
		aSet.insert(aVector[iCount]);
	//Done
	return aSet;
}
void CSuffixTrie::BuildStrings(StringsVector& rVector,
							   const SearchString& rString,
							   const Node* pNode)const
{
	//Sanity check
	if (!pNode)
		return;
	//Is this a final node?
	if (pNode->bFinal)
		//Add to the vector
		rVector.push_back(rString);
	//Iterate all its children
	for (SearchMap::const_iterator aIterator=pNode->aMap.begin();
		 aIterator!=pNode->aMap.end();
		 ++aIterator)
		//Send it to next level
		BuildStrings(rVector,
					 rString+aIterator->first,
					 aIterator->second);
}
void CSuffixTrie::DeleteString(const SearchString& rString)
{
	//Our prev node
	Node* pPrevNode;
	pPrevNode=NULL;
	//Start to find the nodes
	for (int iCount=0;
		 iCount&lt;rString.length();
		 ++iCount)
	{
		//Find the node
		Node* pNode;
		pNode=SearchNode(rString.substr(iCount,rString.length()-iCount),
						 &m_aRoot);
		//Do we have a previous node?
		if (pPrevNode && pNode)
		{
			//We need to delete it
			pNode->aMap.erase(pPrevNode->aChar);
			
			//And delete the node
			delete pPrevNode;
			pPrevNode=NULL;
		}
		//Did we get it?
		if (pNode)
			//What stage are we?
			if (!iCount)
				//Does it have children?
				if (pNode->aMap.empty())
					//We can delete it
					pPrevNode=pNode;
				else
				{
					//Can't be final
					pNode->bFinal=false;
					//Exit
					return;
				}
			//Do we have children
			else if (pNode->aMap.empty())
				//We can delete it
				pPrevNode=pNode;
			else
				//Exit
				return;
	}
}


main()
// TestAhoCorasik.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include "SuffixTrie.h"
#include <fstream>
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
void AC_search(string textx,string patternx)
{
 CSuffixTrie aTree;
 
	CSuffixTrie::_DataFound aData;
	CSuffixTrie::DataFoundVector aDataFound;
    
//Declar file variables
   ifstream  inFile1, inFile2;
      string pattern,text,line;
wchar_t NameBuffer[10000];
      char *T;
	  T = new char[10000];
	  char *p;
	  p = new char[500];
//Inter the pattern file 
 
	pattern=patternx;
	  inFile1.open(pattern.c_str());
       if ( !inFile1 )
        {
          cout<<"Unable to open file. Enter a different name: ";
	      inFile1.clear();
          cin << pattern;
	      inFile1.open(pattern.c_str());
	   }
      
 //Inter the text file  
  
	  text=textx;
	  inFile2.open(text.c_str());
       if ( !inFile2 )
        {
          cout<<"Unable to open file. Enter a different name: ";
	      inFile2.clear();
          cin >> text;
	      inFile2.open(text.c_str());
	   }
//Read the pattern file			
 while(getline(inFile1, line))
		  { 		
			strcpy_s(p, 500, line.c_str());
			
			//char *pp;
			//pp = new char[500];
			//strcpy_s(pp, 500, line.c_str());
			//parseString(pp, p);
			cout<<p&lt;&lt;endl;
            
			//convert a char array to string
            //convert char* to unicode
            string search = p;
           const size_t newsize = 100;
           size_t origsize = strlen(search.c_str()) + 1;
           size_t convertedChars = 0;
           wchar_t wcstring[newsize];
           mbstowcs( wcstring, search.c_str(), newsize); 
           //wcscat_s(wcstring, L" (wchar_t *)");
			
		   
		   //add to the search tree
			aTree.AddString(wcstring);
            
			
 }
    //Build AC Tree.	
	
    aTree.BuildTreeIndex();
    
	
	
//define widechar array?
//Read the pattern file			
	  while(getline(inFile2, line))
		  { 		
			strcpy_s(T, 500, line.c_str());
			//	cout&lt;&lt;T&lt;&lt;endl;
     cout<<T<<endl;
			
            //convert char* to unicode
            string search1 = T;
            const size_t newsize1 = 500;
            size_t origsize = strlen(search1.c_str()) + 1;
            size_t convertedChars = 0;
            wchar_t wcstring1[newsize1];
            mbstowcs( wcstring1, search1.c_str(), newsize1); 
            
        
    // perform the search.
    	  aDataFound=aTree.SearchAhoCorasikMultiple( wcstring1 );
	for (int iCount=0;
		 iCount&lt;aDataFound.size();
		 ++iCount)
		 printf(" AC Match Found :    %S \n",aDataFound[iCount].sDataFound.c_str());
	  }
}
int main(int argc, char* argv[])
{
string pattern,text,line;
 cout<<"Enter text file name.\n";
      cin>>text;	 
   cout<<"Enter patterns file name.\n";
      cin>>pattern;
	 
AC_search(text,pattern);

	return 0;
}
</ctime></string></iostream></fstream></stdio.h></stdlib.h>
Posted
Updated 18-May-11 22:44pm
v5
Comments
ZeeroC00l 19-May-11 3:14am    
--edited 'pre' tag
I think you have to provide some more information where you are getting the problem.
std::out_of_range error will come for lots of reasons.For example if you are accessing invalid index..
Legor 19-May-11 7:02am    
Are you actually thinking somebody has the time to read through all this code for you? at least try to figure out the part where the error occures by debugging it and provide only the detailed code.
Stefan_Lang 19-May-11 8:12am    
You're asking us to do both the compilers and the run-time systems work where you could achieve the same in less than 5 minutes just by using the debugger.

When you run a program the system will put some safety guards around the memory that make sure you don't access invalid addresses. These guards will only trigger when you try to read or write data way outside the memory range that you actually allocated for use.

In most cases, when you get that error something is seriously wrong, for instance you may accidentally access array elements using a negative index, or you have a runaway loop that continually increases an index or address that you access, but never stops.

This has nothing to do with availability of memory, it's just that somewhere your accessing of that memory went afoul.

Use the debugger to pin down the statement that causes the error, and check the address it refers to.
 
Share this answer
 
v2
It's not the amount of memory that is the problem: It will be your code. Somewhere it is accessing memory very badly indeed.
You need to run this through the debugger, and try to work out at least which routine the error is occurring - preferably the line. Then it may be possible to work back from there to whatever you have done to cause it. With out this information, you are going nowhere, I'm afraid!
 
Share this answer
 
I think the cause for this exception is you are accessing an invalid index of an array or a container which does bound checking,unless taking look at the code it is tough to point out where.
You can step over the code using a debugger and see where exactly it happens.
 
Share this answer
 
I see several places where allocated string length doesn't match copied string length. And where they do match, there is no check to see if the copy was successful. There is no point in using strcpy_s() if you don't check the result to see if the copy is valid!

That's just after skimming over main() and the one function that's called there: AC_search().

Some tips:

1. You really should use distinctive variable name rather than 'p' or 'T'

2. extract some of the repetitive work (such as copying strings) into small functions that actually do check for errors and react appropriately. Throw exceptions if you must, return NULL pointers rather than copies that are in an undefined state.

3. Don't use 'magic numbers' such as 100 or 500. Declare some constants that hold that value and then use these constants instead. If used to determine a size, name the constant appropriately so that you recognize which size they represent, and you don't accidentally mix up values (like you did at least once in AC_search())

4. Check return values! I've already mentioned strcpy_s(), but this also true for many other functions that may return an error condition.

That's all for now. Unfortunately the formatting on the code is still messed up and I don't really have the time to fix it or dig my way through it in spite of the formatting. You'd do better by actually using the debugger to pin down the area of code that actually causes the error. For you that's 5 minutes at most. For us it's 15 minutes at least just to make some sense out of all this.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900