2016-06-19 2 views
1

Функция печатает адреса каждой ячейки памяти динамического массива. Правильно ли это?Как распечатать адреса памяти C-String?

int main() 
{ 
    char str[] = "This is a test"; 
    printAddresses(str, strlen(str)); 
} 

template <class type> 
void printAddresses(type *item, int n) 
{ 
    cout << "Printing Addresses..." << endl; 
    for (int i = 0; i < n; i++) 
    { 
     cout << "Index " << i << ": " << ((&item) + i) << endl; 
    } 

} 

Я также слышал, что я должен использовать:

cout << "Index " << i << ": " << (void*) &item[i] << endl; 

, но это дает мне другой адрес памяти. Я не уверен, какой из них прав.

+1

Cast к 'void *' для печати адреса. –

+0

Перерыв с отладчиком и посмотреть. – zmbq

+0

'cout <<" Index "<< i <<": "<< (void *) ((& item [i])) << endl;' –

ответ

1

Правильный адрес - тот, который вы получаете при печати (void*)&item[i].

item уже указатель; так и &item[i]. Вы заинтересованы в печати значения этого указателя, вам нужно отдать его void* перед вызовом << на нем.

При печати ((&item) + i) вы делаете дополнительный уровень косвенности (&item указатель указатель на), так что вы напечатать адрес item -The-указатель, а не адрес, что item указывает на.

Примечание :: Начиная с C++ 11 вы можете использовать функцию std::addressof вместо оператора & для лучшей читаемости и избежать возможных проблем при T обеспечивает перегрузку для оператора &:

cout << "Index " << i << ": " << std::addressof(item[i]) << endl; 
+0

В этом случае почему '' cout << "Индекс" << i << ":" << (item + i) << endl; '' не работает? – user3577478

+0

@ user3577478 Это отличный вопрос! Причина, по которой это не сработает, заключается в том, что оператор << имеет перегрузку для указателя char, который обрабатывает этот указатель как строку C с нулевым завершением, распечатывая его содержимое. При нажатии на указатель void вы вызываете перегрузку, которая печатает адрес, а не контент. – dasblinkenlight

+0

Это имеет смысл. Таким образом, C-строки обрабатываются бит иначе, чем обычные указатели с оператором <<. – user3577478

0

Возможным способом может быть использование C-стиля printf с %p. Так включают <cstdio> попробуйте, например:

const char *sp = "abcde" + 2; // some computation giving a string address 
printf("sp=%p ('%s')\n", sp, sp); 

В качестве альтернативы, литая в (void*) и использовать обычный

std::cout << "sp at " << (void*)sp << std::endl; 
1

Запустить:

#include <iostream> 
#include <cstring> 
using namespace std; 

template <class type> 
void printAddresses(type *item, int n) 
{ 
    cout << "Printing Addresses..." << endl; 
    for (int i = 0; i < n; i++) 
    { 
     cout << "Index " << i << ": " << ((&item) + i) << endl; 
     cout << "Index2 " << i << ": " << (void*) &item[i] << endl; 
    } 

} 

int main() 
{ 
    char str[] = "This is a test"; 
    printAddresses(str, strlen(str)); 
} 

, который в моей машине принтами:

[email protected]:~$ g++ -Wall main.cpp 
[email protected]:~$ ./a.out 
Printing Addresses... 
Index 0: 0x7ffd5c9ead58 
Index2 0: 0x7ffd5c9ead90 
Index 1: 0x7ffd5c9ead60 
Index2 1: 0x7ffd5c9ead91 
Index 2: 0x7ffd5c9ead68 
Index2 2: 0x7ffd5c9ead92 
Index 3: 0x7ffd5c9ead70 
Index2 3: 0x7ffd5c9ead93 
Index 4: 0x7ffd5c9ead78 
Index2 4: 0x7ffd5c9ead94 
Index 5: 0x7ffd5c9ead80 
Index2 5: 0x7ffd5c9ead95 
Index 6: 0x7ffd5c9ead88 
Index2 6: 0x7ffd5c9ead96 
Index 7: 0x7ffd5c9ead90 
Index2 7: 0x7ffd5c9ead97 
Index 8: 0x7ffd5c9ead98 
Index2 8: 0x7ffd5c9ead98 
Index 9: 0x7ffd5c9eada0 
Index2 9: 0x7ffd5c9ead99 
Index 10: 0x7ffd5c9eada8 
Index2 10: 0x7ffd5c9ead9a 
Index 11: 0x7ffd5c9eadb0 
Index2 11: 0x7ffd5c9ead9b 
Index 12: 0x7ffd5c9eadb8 
Index2 12: 0x7ffd5c9ead9c 
Index 13: 0x7ffd5c9eadc0 
Index2 13: 0x7ffd5c9ead9d 

Теперь думаю какую последовательность вы ожидаете увидеть для сохраненных символов? Вы ожидаете, что каждый персонаж будет рядом с предыдущим (конечно), и каждый из них возьмет 1 ячейку памяти. Это должно сказать вам, что:

(недействительными *) & пункт [я]

является правильным, что нужно сделать.


Также обратите внимание, что комментарий zmbq об использовании отладчика для выяснения имеет смысл.


Наконец, я хотел бы посоветовать вам прочитать: Printing array element memory adresses C and C++, why different output?

0

Причина вы получаете другой адрес памяти, потому что ваш код является неправильным.

void printAddresses(type *item, int n) 

item является параметром указателя на вашу функцию printAddresses шаблона. Таким образом, в следующем выражении:

cout << "Index " << i << ": " << ((&item) + i) << endl; 

Поэтому:

&item 

становится адрес параметра вашей функции шаблона, а не адрес массива.

Вот почему:

(&item)+i 

неправильно, и совершенно бессмысленно. Здесь адрес параметра для вашей функции шаблона не очень полезен.

(void*) &item[i] 

Правильный ответ.

+0

Привет, можете ли вы сказать мне, почему '' cout << "Index" << i << ":" << (item + i) << endl; '' не работает? – user3577478

+0

Поскольку 'byte' является, скорее всего,' char', поэтому 'std :: ostream' будет пытаться напечатать строку символов, а не адрес указателя. Он не похож ни на какой другой, произвольный 'char *' на 'operator <<'. –

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