Access Violation in a simple C++ program


I wrote a simple C++ program that removes the duplicate spaces in a string. The function doing the work is RemoveDupSpaces:



char* RemoveDupSpaces(char *s) {


      char *a = s; char *b = s;


      while(*a != '\0') {


            while(*a != ' ' && *a != '\0') *b++ = *a++;


            // copy one space


            if(*a == ' ') *b++ = *a++;


            // ignore other spaces


            while(*a == ' ') a++;


      }


      *b = '\0';


      return s;


}


Main calls this simple function, passing it a string:



      std::cout << RemoveDupSpaces(" this   is a   test   string for    removing duplicate     spaces         ");


 


When I execute the program, I get the following access violation:



Access violation - code c0000005 (first chance)


First chance exceptions are reported before any exception handling.


This exception may be expected and handled.


eax=00417928 ebx=7ffde000 ecx=00417928 edx=00342c20 esi=0012fe6c edi=0012fe60


eip=0041194a esp=0012fd7c ebp=0012fe60 iopl=0         nv up ei pl zr na pe nc


cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246


 


So what’s going on? Let’s take a look at the stack:



0:000> kP


ChildEBP RetAddr 


0012fe60 00414ada StringOperations!RemoveDupSpaces(


                     char * s = 0x00417928 " this   is a   test   string for    removing duplicate     spaces         ")+0x7a


0012ff68 00412bb8 StringOperations!wmain(


                     int argc = 1,


                     wchar_t ** argv = 0x00345a90)+0x3aa


0012ffb8 004129ff StringOperations!__tmainCRTStartup(void)+0x1a8


0012ffc0 7c817067 StringOperations!wmainCRTStartup(void)+0xf


0012fff0 00000000 kernel32!BaseProcessStart+0x23


 


Ok, no surprise here. I am in RemoveDupSpaces. We can take a look at the local variables:



0:000> dv -V


0012fe68 @ebp+0x08               s = 0x00417928 " this   is a   test   string for    removing duplicate     spaces         "


0012fe4c @ebp-0x14               b = 0x00417928 " this   is a   test   string for    removing duplicate     spaces         "


0012fe58 @ebp-0x08               a = 0x00417928 " this   is a   test   string for    removing duplicate     spaces         "


 


Why the access violation? Let’s take a look at the memory at the address 0x00417928.



0:000> !address 0x00417928


    00400000 : 00417000 - 00003000


                    Type     01000000 MEM_IMAGE


                    Protect  00000002 PAGE_READONLY


                    State    00001000 MEM_COMMIT


                    Usage    RegionUsageImage


                    FullPath StringOperations.exe


 


We are trying to write in a read only location. To understand the issue, we need to delve a little in C++ memory management. We have 4 major memory segments:


1.       Global: global variables (scoped to the entire program), static variables, static class and namespace members. This segment is fixed in size.


2.       Code (text): the compiled program. This part is read only.


3.       Heap: dynamically allocated variables.


4.       Stack: parameters, automatic and temporary variables.


 


If you want to read more, you can start here. So, our problem is that the string is allocated from a read only segment. A simple fix: dynamically allocate the string in main will solve the issue, because this will give me read-write address:


 



const char * const s = " this   is a   test   string for    removing duplicate     spaces         ";


      char *p = new char[strlen(s) + 1];


      strcpy_s(p, strlen(s) + 1, s);


      std::cout << RemoveDupSpaces(p);


      delete [] p;

Skip to main content