Heap corruption when deleting a string

戏子无情 提交于 2019-12-06 04:46:27

Change:

char* rawString = new char[strLen];

to:

char* rawString = new char[strLen + 1];

You're accessing past the reserved bytes for your string. You reserved strLen characters, but put a \0 at the character strLen. Counting as C arrays from 0, character strLen is at position strLen + 1, so you're putting a value outside the reserved space for the string. You should reserve strLen + 1 in the second line of your main for your code to work.

int strLen = Read<int>() probably only returns the length of a non-null-terminated string, and when you try to write the \0 byte to the string, you run into buffer overflow problems.

You should check what strLen is, and most likely you either have to allocate like this:

char *rawString = new char[strlen+1];

Or use the overloaded constructor of std::string(const char *, size_t n) like this:

std::string retVal(rawString, strlen);

Since arrays are 0-indexed in c++, when you create an array of size strLen and then place a 0 at position strLen, you are writing that zero one after the end of the array you allocated.

Many advices so far, but none which address the exception safety issue: how do you get rid of that potential memory leak ?

There are two ways to avoid allocating with new (and thus facing a memory leak). The first is extremely simply and makes use of a compiler extension known as VLA for Variable Length Array:

std::string readString()
{
  int strLen = Read<int>();
  char rawString[strLen+1]; // VLA: the length is determined at runtime
                            // but the array is nonetheless on the stack
  Read(rawString, strLen);
  rawString[strLen] = '\0';

  std::string retVal(rawString);
  return retVal;
}

The other is compliant with the standard: string has an internal buffer which you can access (thanks to GMan, data is not the right access method)

std::string readString()
{
  int strLen = Read<int>();

  std::string retVal(strLen, '\0'); // no need to allocate extra space

  Read(&retVal[0], strLen);      // &retVal[0] gives access to the buffer

  return retVal;
}

I do believe that the last version is MUCH better. There is no longer any copying involved :)

 rawString[strLen] = '\0';

Writes the NUL off the end of the space you have allocated.

If strLen is 10, then you allocate space for 10 characters, read 10 characters, and write this NUL in position 11. Ooops

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!