std::swap with pointer gives segmentation fault
I have a very simple program but this is giving me a seg fault. I have been struggling from a long time to figure this out. Please help.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
main() {
char *database;
int ndata=4;
database="aaa4baa3bcd2aab5";
char *dummy;
dummy=(char *)malloc(16);
memcpy(dummy,database,16);
printf("%s\n",dummy);
std::swap(databas开发者_开发技巧e,dummy);
dummy[2]='a';
}
Assigning to the dummy variable before the swap works fine. What is the problem after the swap. thanks
database
points to a string literal, which is put into readonly memory, you cannot write to it, even though the pointer is of type char *
instead of const char*
. Strictly speaking the literal is of type const char *
and the assignment to the char *
typed pointer should be disallowed, but this is a legacy implicit conversion that is still allowed today.
The swap
only swaps the pointers themselves, not what they point to. So after swap
dummy refers to the memory that contains the string literal, which you are not allowed to write to.
Perhaps you should consider using std::string
for your string handling, which does allow simple assignments and such and thus allows swap
to work as you expect.
I'll rewrite your code a bit without changing its meaning
char *database = "aaa4baa3bcd2aab5";
char *dummy = (char *)malloc(16);
memcpy(dummy,database,16);
printf("%s\n",dummy);
std::swap(database,dummy);
dummy[2]='a'; //here you in fact attempt to modify a string literal
after you've done swap
dummy
points where database
pointed previously and that's an address of a string literal which you are not allowed to modify.
Also please note that the string literal has 16 characters plus a null terminator - total 17 characters, so once you've allocated the buffer of size 16 and copied the literal there the result is not null terminated.
String literals are immutable, and attempts to modify the string may lead to runtime failure. Even though the language allows char*
to point to a string literal, you should always mark the pointee const in this case: const char* database = "aaa4baa3bcd2aab5";
If you do so, the compiler will inform you that you can't swap those pointers (because now their types are not compatible), saving you from the trouble of hunting down resulting runtime errors.
Aside, you shouldn't print dummy
as string, because it is not null-terminated.
database contains 17 characters: the 16 you count plus the final '\0'. You copy only the first 16, so dummy does not contain a final '\0'.
So printf("%s\n",dummy);
will read past the end of dummy, and might access memory it is not allowed to read.
精彩评论