If the question is "I know it's wrong, but why did it do that?", there are sort of two ways of answering it.
(1) Undefined behavior means anything can happen. Taking an array of size 8 and writing 13 characters to it is a really wrong thing to do. You're overwriting five bytes of memory that were presumably in use for something else, so overwriting them means... anything can happen. (But now I'm repeating myself.)
I know you asked the question in all sincerity, but I have to say, to me these questions always sound like: "I ran through a busy intersection when the sign said Don't Walk. A blue car ran over me, and I broke my left leg. I don't understand why. Why wasn't I hit by a red truck? Why didn't I break my right arm?"
(2) Let's look at a likely layout of the memory allocated for this program:
+----+----+----+----+----+----+----+----+
a: | S | o | l | a | r | i | s | \0 |
+----+----+----+----+----+----+----+----+
+----+----+----+----+
ptr: | 78 | 56 | 34 | 12 |
+----+----+----+----+
+----+----+----+----+----+----+
0x12345678: | L | i | n | u | x | \0 |
+----+----+----+----+----+----+
Here I'm imagining that the string "Linux"
is stored at address 0x12345678
, so ptr
holds that value. I'm imagining that your machine uses 32-bit pointers. (These days, though, it might well use 64.) I'm imagining that your machine uses "little endian" byte order, meaning that the bytes making up the pointer p
are stored in the opposite order in memory than you might expect.
You said that after calling strcat
, a
printed out the concatenated string you expected, but the program crashed when you tried to print ptr
. Let's change the printout of ptr
to
printf("%p: %s\n", ptr, ptr);
Before the call to strcat
, this will print something like
0x12345678: Linux
But here's what the call to strcat
actually does:
+----+----+----+----+----+----+----+----+
a: | S | o | l | a | r | i | s | L |
+----+----+----+----+----+----+----+----+
+----+----+----+----+
ptr: | i | n | u | x | \0
+----+----+----+----+
Now, the printout of ptr
is going to be something like
0x78756e69: Segmentation violation (core dumped)
You overwrote the pointer ptr
, so it no longer points to address 0x12345678
where the string "Linux"
is stored, it now points to location 0x78756e69
, where those hex digits come from the characters i n u x
. If you don't have permission to access address 0x78756e69
, you'll get a crash. If you do have permission to access location 0x78756e69
, you'll get some garbage string printed.
Now, with all of that said, it's important to note that this is not necessarily what will happen. I've assumed that the compiler stored the pointer ptr
right after the array a
in memory. That's one possibility, but obviously not the only possibility. If the compiler happened to store ptr
somewhere else, then something else would get overwritten by inux
, and something else might go wrong. Or nothing might go wrong. (In other words, you might get hit by the blue car, or you might get hit by the red truck, or you might get lucky and make it across the street without being hit at all.)
Addendum: I've just looked at your post more carefully, and I see that gdb told you that ptr
had changed to 0x78756e69
, and that it couldn't access the memory there. But now we know where that strange value 0x78756e69
probably came from. :-)