Вы объявили три строки:
sample1
, на которые указывает p2
sample1
, на которые указывает str[0]
sample2
, на который указывает str[1]
Поскольку это все " строковые литералы ", они не могут быть изменены и хранятся только для чтения.
Компилятору разрешено распознавать, что на самом деле у вас есть только две уникальные строки, и, таким образом, хранятся только две строки (это зависит от реализации).
Что именно является 0x4005f8
?
То, что вы найдете в памяти, вероятно, примерно так:
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
То есть:
-
p2
переменная: - расположена по адресу
0x7fffffffdb38
- Имеет значение
0x4005f8
- Переменная
str[0]
: - Расположен по адресу
0x7fffffffdb20
- Имеет значение
0x4005f8
- Адрес памяти
0x4005f8
является началом строки sample1
, то есть: s
символ - Памятьy адрес
0x4005f9
- следующий символ строки sample1
, т. е. символ a
- ...
0x4005fa
равен m
- ...
0x4005fb
is p
- ...
0x4005fc
is l
- ...
0x4005fd
is e
- ...
0x4005fe
is1
- ...
0x4005ff
равно \0
или " nul ", что завершает строку
При тестировании p2 == str[0]
,Вы проверяете, что значения, хранящиеся в обеих переменных, одинаковы.Значения являются базовым адресом строки.Они содержат « одинаковую строку» и, таким образом, содержат одинаковые значения.
Вполне возможно сохранить строку « same » (т. Е. Тот же текст)в двух разных местах памяти, и в такой ситуации этот тест не пройден.
То, что вы фактически говорите здесь, что две строки - это " один и тот же экземпляр ", они находятся вто же место в памяти, и, следовательно, должно иметь одинаковое содержимое.
... и как его распечатать?
Вы можете распечатать как один символза один раз, используя x/1c
, или как строку с нулевым символом в конце, используя x/1s
(gdb
правильно обрабатывает строки C).
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;
}
Компиляция:
gcc main.c -o main -g
Запуск:
$ 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"
Печать трех " строк " с адреса 0x400684
:
(gdb) x/3s 0x400684
0x400684: "sample1"
0x40068c: "sample2"
0x400694: "true"
Печать16 символов из адреса 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'
Печать адресов, хранящихся в p2
, str[0]
и str[1]
:
(gdb) x/1a &p2
0x7fffffffe308: 0x400684
(gdb) x/1a &str[0]
0x7fffffffe310: 0x400684
(gdb) x/1a &str[1]
0x7fffffffe318: 0x40068c