2016-06-10 3 views
1

Идущий по книгам, первая соиЬ линия должна напечатать мне адрес места, где хранится переменная символ б, который, кажется, в случае переменной Int А слишком , Но первый оператор cout выдает нечетный 'dh^#', а второй оператор корректно печатает шестнадцатеричное значение ' ox23fd68'. Почему это происходит?Указатель символа в C++

#include<iostream> 
    using namespace std; 

    int main() 
    { 
     char b='d'; 
     int a=10; 
     char *c=new char[10]; 
     c=&b; 
     int *e=&a; 
     cout<<"c: "<<c<<endl; 
     cout<<"e: "<<e; 
    } 
+0

Подсказка: «по книгам» должен «c:» «распечатать адрес тоже? –

+3

Это не плохой вопрос, но, возможно, он ответил в другом месте.Короткий ответ заключается в том, что C++ унаследовал трактовку C 'char *' как «Вероятно, набор печатных вещей». –

+1

Из каких книг вы получили эту идею? – molbdnilo

ответ

3

У этой программы есть проблемы. Существует утечка памяти.

char *c=new char[10]; 
c=&b; 

Это выделяет 10 символов на кучу, но затем указатель кучи перезаписаны с адресом переменной b.

Когда char* записан в cout с operator<<, тогда он рассматривается как C-строка с нулевым завершением. Так как адрес b инициализируется одним символом, содержащим d, то op<< продолжает поиск в стеке, набирая первый нулевой символ. Кажется, что это было найдено после нескольких символов, поэтому записано dh^# (d - значение переменной b остальное - это всего лишь некоторые случайные символы, найденные в стеке до 1-го \0).

Если вы хотите, чтобы получить адрес, попробуйте использовать static_cast<void*>(c).

Мой пример:

int main() { 
    char *c; 
    char b = 'd'; 
    c = &b; 
    cout << c << ", " << static_cast<void*>(c) << endl; 
} 

выход:

dÌÿÿ, 0xffffcc07 

Смотрите странные символы после 'D'.

Надеюсь, это поможет немного!

5

Существует перегрузка operator<<(std::basic_ostream) не являющегося членом для типа const char*, который не пишут адрес, а скорее (предположительно) С-типа строка 1). В вашем случае, поскольку вы назначили адрес одного символа, нет терминатора NUL и, следовательно, нет допустимой строки C-стиля. Код показывает undefined behavior.

Поведение для int* отличается, так как нет специальной обработки указателей на int, и оператор записывает адрес в поток, как и ожидалось.

Если вы хотите, чтобы получить адрес символа вместо этого, использовать static_cast:

std::cout << static_cast<void*>(c) << std::endl; 


1) Строка C-стиль представляет собой последовательность символов, концевую NUL характер ('\0').

Смежные вопросы