Friday, July 31, 2009

Why does my C++ program crash?

I'm new to C++, why does this code cause the program to crash?





#include %26lt;iostream%26gt;





using namespace std;





char * tolowercase(char * ptr)


{


while( *ptr )


{


*ptr = tolower(*ptr); // Renders lowercase


ptr++;


}


return ptr;


}





int main()


{


char * str = "Hello world!";


strcpy (str, tolowercase(str));


cout %26lt;%26lt; str;


return 0;


}

Why does my C++ program crash?
1. First, warning of a mistake you made, but this is not the reason of the crash:





Inside tolowercase() method, the final value of ptr after the execution of the while loop is such that it is pointing to string null (ascii 0). That is why the while loop terminated in the first place. You are returning the same pointer (which now points to 0). So your strcpy() call is trying to copy from a string whose first character is string null.





But while that would result in wrong functionality (cout would print out a blank string), that should not result in a crash. Because if a char* pointer points to 0 (null), even then it is a valid string (of length zero).





But beware of this mistake - once you solve the crash, this mistake will result in wrong functionality.





2. Now for the crash: The crash is probably happening because strcpy's first argument cannot be const char *.





When you declare and assign a string like this:





char * str = "Hello world!";





str becomes a const char *.





If you try to overwrite the contents of a const pointer, it might crash.





Also, tolowercase() method must, by nature, take a non-const pointer as argument, but again you are passing a const pointer as argument. So which one of these reasons is causing the crash is anybody's guess, but your program has serious problems with it.





I could tell you how to overcome these problems, but you should try to solve them youself, now that you know the areas that you need to look at. If you need further help, you can message me. Thanks.
Reply:I dont know C++. But this looks like you are returning a ptr which is NULL from tolowercase. You are increasing the ptr till it becomes null and returning it. Instead you could store the char ptr somewhere in a temp char * (before the loop starts) and return that instead
Reply:Your program tries to change the string in place, one character at a


time, but "Hello, world!" is a constant string and can't be changed.





If the program were technically correct, it would declare str as


const char *const str = "Hello, world!"


because it is really a constant pointer to a constant string.


The compiler would then bark at you when you tried to use


it in a way that changed either the string or the pointer itself.





This rule didn't always exist (or wasn't always enforced), so there are


lots of old code examples that do write over strings like this.





There are a couple of ways around this. One way is to declare str as


a character array and copy "Hello, world!" into it. Another way is to


give tolowercase() two parameters and copy the string into a new


buffer while never changing the old.





But all of these are just teaching exercises. When you really start


programming in C++, you would use std::string and the conversion


would look something like this:





std::string str("Hello, world!");


std::transform(str.begin(), str.end(), str.begin(), tolower)
Reply:#include %26lt;iostream%26gt;





using namespace std;





char * tolowercase(char * ptr)


{


char *temp = ptr;


while( *ptr )


{


*ptr = tolower(*ptr); // Renders lowercase


ptr++;


}


return temp; // This is so the return value is the start of the string not the end.


}





int main()


{


char str[40] = "Hello world!"; // Change this line so that "Hello world!" is stored in the string array. Previously you had a pointer to memory containing "Hello world!".


strcpy (str, tolowercase(str));


cout %26lt;%26lt; str;


return 0;


}





This will work without 'crashing'.


No comments:

Post a Comment