You have declared three strings:
- sample1, pointed to by- p2
- sample1, pointed to by- str[0]
- sample2, pointed to by- str[1]
As these are all "string literals", they cannot be changed, and are stored read-only.
The compiler is permitted to recognise that you only actually have two unique strings, and thus only store the two strings (it depends on the implementation).
What exactly is 0x4005f8?
What you'll find in memory is probably something like this:
0x0000004005f8  's'
0x0000004005f9  'a'
0x0000004005fa  'm'
0x0000004005fb  'p'
0x0000004005fc  'l'
0x0000004005fd  'e'
0x0000004005fe  '1'
0x0000004005ff  '\0'
0x000000400600  's'
0x000000400601  'a'
0x000000400602  'm'
0x000000400603  'p'
0x000000400604  'l'
0x000000400605  'e'
0x000000400606  '2'
0x000000400607  '\0'
...
0x7fffffffdb20  0xf8
0x7fffffffdb21  0x05
0x7fffffffdb22  0x40
0x7fffffffdb23  0x00
0x7fffffffdb24  0x00
0x7fffffffdb25  0x00
0x7fffffffdb26  0x00
0x7fffffffdb27  0x00
...
0x7fffffffdb38  0xf8
0x7fffffffdb39  0x05
0x7fffffffdb3a  0x40
0x7fffffffdb3b  0x00
0x7fffffffdb3c  0x00
0x7fffffffdb3d  0x00
0x7fffffffdb3e  0x00
0x7fffffffdb3f  0x00
That is to say that:
- The p2variable:
- Is located at address 0x7fffffffdb38
- Has a value of 0x4005f8
 
- The str[0]variable:
- Is located at address 0x7fffffffdb20
- Has a value of 0x4005f8
 
- The memory address 0x4005f8is the beginning of thesample1string, i.e: thescharacter
- The memory address 0x4005f9is the next charater of thesample1string, i.e: theacharacter
- ... 0x4005faism
- ... 0x4005fbisp
- ... 0x4005fcisl
- ... 0x4005fdise
- ... 0x4005feis1
- ... 0x4005ffis\0or "nul", which terminates the string
When you test p2 == str[0], you test that the value stored in both variables are the same. The values are the base address of the string. They hold the "same string, and thus hold the same values.
It is entirely feasible to store the "same" string (i.e: the same text) in two different memory locations, and in such a situation this test would fail.
What you're effectively saying here that the two strings are the "same instance", they reside at the same place in memory, and thus must have the same content.
... and how do I print it?
You can either print is as a single character at a time using x/1c, or as a nul-terminated string using x/1s (gdb handles C strings properly).
main.c:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
        char *p2 = "sample1";
        char *str[2] = { "sample1", "sample2" };
        if (p2 == str[0]) {
                printf("true\n");
        }
        return 0;
}
Compile:
gcc main.c -o main -g
Run:
$ gdb ./main
[...]
(gdb) start
Temporary breakpoint 1 at 0x4005a5: file main.c, line 4.
Starting program: /home/attie/stackoverflow/56475101/main
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe418) at main.c:4
4       int main(int argc, char *argv[]) {
(gdb) list
1       #include <stdio.h>
2       #include <stdlib.h>
3
4       int main(int argc, char *argv[]) {
5               char *p2 = "sample1";
6               char *str[2] = { "sample1", "sample2" };
7
8               if (p2 == str[0]) {
9                       printf("true\n");
10              }
(gdb) b 8
Breakpoint 2 at 0x4005cc: file main.c, line 8.
(gdb) c
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe418) at main.c:8
8               if (p2 == str[0]) {
(gdb) print p2
$1 = 0x400684 "sample1"
(gdb) print str[0]
$2 = 0x400684 "sample1"
(gdb) print str[1]
$3 = 0x40068c "sample2"
Print three "strings" from address 0x400684:
(gdb) x/3s 0x400684
0x400684:       "sample1"
0x40068c:       "sample2"
0x400694:       "true"
Print 16 characters from address 0x400684:
(gdb) x/16c 0x400684
0x400684:       115 's' 97 'a'  109 'm' 112 'p' 108 'l' 101 'e' 49 '1'  0 '\000'
0x40068c:       115 's' 97 'a'  109 'm' 112 'p' 108 'l' 101 'e' 50 '2'  0 '\000'
Print the addresses stored at p2, str[0] and str[1]:
(gdb) x/1a &p2
0x7fffffffe308: 0x400684
(gdb) x/1a &str[0]
0x7fffffffe310: 0x400684
(gdb) x/1a &str[1]
0x7fffffffe318: 0x40068c