2016-06-19 15 views
1

Die Funktion druckt die Adressen der einzelnen Speicherstelle des dynamischen Arrays. Ist das der richtige Weg?Wie Speicheradressen von C-String auszudrucken?

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; 
    } 

} 

Ich habe auch gehört, dass ich verwenden sollte:

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

aber das gibt mir verschiedene Speicheradresse. Ich bin mir nicht sicher, welcher richtig ist.

+1

Cast 'void *' um die Adresse auszudrucken. –

+0

Brechen Sie mit dem Debugger und sehen. – zmbq

+0

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

Antwort

1

Die korrekte Adresse ist die, die Sie beim Drucken erhalten (void*)&item[i].

item ist bereits ein Zeiger; so ist &item[i]. Sie sind daran interessiert, den Wert dieses Zeigers zu drucken, Sie müssen ihn auf void* vor dem Aufruf << auf es umwandeln.

Wenn Sie ((&item) + i) drucken Sie eine zusätzliche Dereferenzierungsebene machen (&item ist ein Zeiger-to-Zeiger), so wird die Adresse des item -the-Zeiger zu drucken, nicht die Adresse, was zu item zeigt.

Hinweis :: Beginnend mit C 11 ++ Sie std::addressof Funktion anstelle von Operator & zur besseren Lesbarkeit verwenden können, und mögliche Probleme zu vermeiden, wenn T eine Überlastung für Betreiber bietet &:

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

In diesem Fall, warum << cout << "Index << << <<:" << (Element + i) << endl; " nicht funktioniert? – user3577478

+0

@ user3577478 Das ist eine ausgezeichnete Frage! Der Grund, warum dies nicht funktionieren würde, ist, dass der Operator << eine Überladung für den char-Zeiger aufweist, der diesen Zeiger als eine mit Null abgeschlossene C-Zeichenfolge behandelt und seinen Inhalt druckt. Wenn Sie in den void-Zeiger umwandeln, erzwingen Sie eine Überladung, die die Adresse und nicht den Inhalt ausgibt. – dasblinkenlight

+0

Das macht viel mehr Sinn. So werden C-Strings anders als normale Zeiger mit dem Operator << behandelt. – user3577478

0

Eine Möglichkeit könnte sein, den C-Stil printf mit %p zu verwenden. So umfassen <cstdio> dann versuchen, zum Beispiel:

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

Alternativ zu gieße (void*) und üblichen

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

Run verwenden diese:

#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)); 
} 

die in meiner Maschine druckt:

[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 

Jetzt denken was Sie Sequenz erwarten für gespeicherte Zeichen zu sehen? Sie erwarten, dass jedes Zeichen (natürlich) an das vorherige angrenzt und dass jeder eine Speicherzelle belegt. Das sollte Ihnen sagen, dass:

(void *) & item [i]

ist das Richtige zu tun.

Beachten Sie auch, dass zmbq's Kommentar, über die Verwendung eines Debuggers, um herauszufinden, auch Sinn macht.


Abschließend möchte ich empfehlen Ihnen zu lesen: Printing array element memory adresses C and C++, why different output?

0

Der Grund, warum Sie eine andere Speicheradresse erhalten ist, weil Ihr Code ist fehlerhaft.

void printAddresses(type *item, int n) 

item ist ein Zeiger-Parameter auf Ihre printAddresses Template-Funktion. Also, in dem folgenden Ausdruck:

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

Deshalb:

&item 

wird die Adresse des Parameters auf Ihre Template-Funktion, und nicht die Adresse des Arrays. Diese

Deshalb:

(&item)+i 

falsch ist, und ist völlig sinnlos. Die Adresse des Parameters zu deiner Template-Funktion ist hier nicht wirklich sinnvoll.

(void*) &item[i] 

Ist die richtige Antwort.

+0

Hallo kannst du mir sagen, warum '' cout << "Index" << i << ":" << (item + i) << endl; '' nicht funktionieren? – user3577478

+0

Da 'Byte' höchstwahrscheinlich ein' char' ist, wird 'std :: ostream' versuchen, eine Zeichenkette anstelle einer Zeigeradresse zu drucken. Es sieht nicht anders aus, als irgendein anderes 'char *' an 'operator <<' zu übergeben. –