I have the following code written in C++ to extract a given range of text in a Piece Table data structure. Here is the function of class PieceTable that stores the given range of text in the character array buffer :
void PieceTable::getTextInRange(unsigned __int64 startPos, unsigned __int64 endPos, char buffer[]){
char* totalBuffer = new char[getSize() + 2];
getBuffer(totalBuffer);
if(endPos >= getSize())
endPos = getSize() - 1;
cout<<"startPos : "<<startPos<<endl;
cout<<"endPos : "<<endPos<<endl;
memcpy(buffer, &totalBuffer[startPos], endPos - startPos + 1);
buffer[endPos - startPos + 2] = '\0';
if(totalBuffer != 0)
delete[] totalBuffer;
totalBuffer = 0;
}
Here is the piece of code in the main method which i use to test this code :
temp2 = new char[end - start + 2]; //changing 2 to 3 solves the problem
pieceTable.getTextInRange(Start, end, temp2);
for(int i = 0; i< end - start + 1; i++)
cout<<temp2[i];
cout<<endl;
if( temp2 != 0)
{
delete[] temp2; //this line causes the heap corruption error
temp2 = 0;
}
Declaration of temp2 :
char* temp2;
Whenever the program encounters the delete[] temp2 statement, there is a heap corruption error. The problem does not occur if I allocate memory for temp2 as:
temp2 = new char[end - start + 3]
So, basically changing the length solves the problem. I know that I am messing up with the lengths somewhere, but I can’t figure out where.
EDIT :
getSize() :
__int64 PieceTable::getSize()
{
return dList.getLength(dList.getBack());
}
I am using a piece table data structure. Here it is, inside this paper:http://www.cs.unm.edu/~crowley/papers/sds.pdf
I may be wrong, but I don’t think that there is any problem with getSize(), since the function I use to retrieve the length of the entire buffer getBuffer, works as shown in the code.
In
PieceTable::getTextInRange, you have this line:and when you allocate the thing that you pass in as
bufferyou allocate like this:Lets put in some real numbers…
which is equivalent to:
Well, there’s your problem. If you do
new char [5]you get an array that has valid indexes from 0 through 4. 5 is not a valid index into this array.Might I suggest that you make it a rule that you only break in the most of extenuating of circumstances that you always specify ranges in terms of [begin, end) like the STL does. This means you specify one past the last desired index for end. This makes range calculation math much less error prone. Also, the consistency of the interface with the way STL works makes it easier to work with. For example, calculating the size of the range is always
end - beginwith this scheme.There is an old (circa 1982) paper by E.W. Dijkstra that gives some good reasons why this scheme for expressing ranges is the best one.