Question

I'm trying to do some classic C development in Visual C++ 2008 that will modify the characters of a string like so:

void ModifyString(char *input)
{
  // Change first character to 'a'
  *input = 'a';
}

I'm getting a unhandled exception when I try to change a character. It seems like I could do this in Visual Studio 6 or using gcc, but maybe I'm just forgetting something. Does Visual Studio somehow pass char* by value (managing memory). If so, how do I turn this off?

Was it helpful?

Solution

You're probably passing a string literal somewhere:

ModifyString("oops");  // ERROR!

C and C++ allow you to implicitly cast from string literals (which have type const char[]) to char*, but such usage is deprecated. String constants are allowed to be allocated in read-only memory (and they usually are), so if you attempt to modify them, you'll get an access violation (aka segmentation fault or bus error). If the compiler doesn't put string constants in read-only memory, the program will still work, but it is undefined behavior.

The correct way to do this is to copy the string into a writeable buffer:

// one way:
char mystring[] = "test";
ModifyString(mystring);  // ok

// another way:
char mystring[64];  // make sure this is big enough!!
strcpy(mystring, "test");
ModifyString(mystring);  // ok

OTHER TIPS

Is the input a string literal? That's probably the problem. Otherwise you'll need to post more code, as the pointer has somehow ended up pointing at a readonly location in memory.

It's impossible to answer this question without seeing how ModifyString is called. The function itself is correct assuming it's contract is to be passed a non-NULL value.

However it's possible for the call site to fail by doing any number of things

  • Passing NULL
  • Passing const char by means of an evil cast

I can't say exactly why this doesn't work, but the problem is in your code, not Visual Studio. For some reason, you are passing an invalid pointer to the function. It is either a null pointer, or it points to some address you don't have read access to.

If you post some more of the code (where is the function called from, and how is it called?), we may be able to point out the exact problem.

The reason it worked in GCC or VC6 is quite simply that it is undefined behavior. The C++ standard doesn't say that "this should work", or "this should cause a crash". Anything can happen if you write to memory you don't have access to. And depending on the compiler, and the system you're running the application on, the address you end up accessing will vary. By sheer luck, you hit an address that caused an access violation when compiled with VC2008. Under GCC and VC6, you weren't as lucky, and got code which appeared to work, and simply wrote to some garbage address.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top