2013-02-11 3 views
1

Привет, Я тренировался с размещением нового и использовал его для создания объектов. Рассмотрим следующий пример:разница между (void *) и &

class PNewTesting 
{ 
private: 
    string words; 

public: 
    PNewTesting(const string & w = "Placement new testing"); 
}; 

PNewTesting::PNewTesting(const string & w) 
{ 
    words = w; 
    cout << words << " constructed" << endl; 
} 


int main() 
{ 
    char * buffer = new char[BUF]; 

    PNewTesting *p1,*p2; 

    p1 = new (buffer)PNewTesting; 

    p2 = new PNewTesting("Placing object in heap"); 

    cout << "Memory addresses: " << endl; 
    cout << "buffer: " << (void *)buffer << endl; 
    cout << "object placed in buffer: " << p1 << endl; 
    cout << "object in heap: " << p2 << endl; 
} 

Деталь сбивает с толку меня, что когда я пишу cout << "buffer: " << &buffer << endl;, это дало бы мне другой адрес при написании cout << "buffer: " << (void *)buffer << endl;

Вопрос, в чем разница между &buffer и (void*)buffer, и почему каждый из них дает мне другой адрес.

+2

Это совершенно не связано с размещением новых, кстати. –

+0

Ах, извините, просто начинающий C++, так и не понял. –

+0

Это прекрасно.Но теперь вы знаете :) –

ответ

3

Ваш вопрос может быть essentially reduced to:

#include<iostream> 

int main() 
{ 
    int i = 10; 
    int *ptr = &i; 

    std::cout<<(void*)ptr<<"\n"; 
    std::cout<<(void*)&i<<"\n"; 
    std::cout<< &ptr<<"\n"; 
} 

Выход:

0xbfa080b8 
0xbfa080b8 
0xbfa080bc 

ptr дает адрес объекта указатель, указывающий на то есть такой же, как &i.
&ptr указывает адрес места, где хранится указатель.

+0

+1 для простого и совершенно четкого ответа. – LihO

+0

Спасибо за ваш ответ. То, что я до сих пор не совсем понимаю, это то, что делает (void *) и я? Все, что я знаю, это то, что он приводит к типу void, но не слишком уверен в цели этого. –

+0

@AliAlamiri: Кастинг адреса целочисленного указателя не имеет большого смысла. Кастинг адреса указателя на char ('char *') требуется, когда вам нужно вывести адрес с помощью 'std :: cout', потому что если вы не сделаете так,' operator <<' интерпретирует это как строку символов и пытается распечатать последовательность символов вместо адреса. Обратите внимание, что эта неоднозначность возникает из-за того, что 'operator <<' обеспечивает [перегрузку для указателей на символы] (http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/) –

1

Выражение &buffer предоставит вам адрес buffer, который находится где-то в вашем стеке.

expresson (void *)buffer даст вам адрес, содержащийся в буфере, как указатель недействительным (в данном случае это означает, что cout будет выводить значение как HexNumber, представляющий указатель, а не пытаться, например, для печати .. значение в виде строки, которая была бы то, что код будет нормально делать с char *

1

Один из этих дисплеев адрес переменной, другой отображает значение переменной Рассмотрим эти:

int i = 7; 
std::cout << &i << "\n"; 
std::cout << i << "\n"; 

Первый показывает адрес переменной, называемой i (скорее всего большое четное число). Остальное отображает его значение (7).

Аналогично:

char *buffer; 
std::cout << &buffer << "\n"; 
std::cout << (void*)buffer << "\n"; 

Прежние отображает адрес buffer. Последняя отображает значение литого.

1

Разница проста. buffer является указателем на символ, поэтому (void*)buffer - это местоположение в памяти выделенного массива символов (в качестве указателя void). &buffer, с другой стороны, является местом в памяти bufferсебя.

Диаграмма может помочь; это символизирует происходящее и не отражает то, как будет выглядеть реальный формат памяти!

Memory 
AB AB AB AB 00 00 00 08 <-- buffer = 00 00 00 08; the characters are stored starting at 0x08 
      ^
      |---------  &buffer is the memory location of buffer, and is 0x04 
30 31 32 32 AB AB AB AB 
^ 
|-------- char array starts at 0x08, and contains the string "1234" 
Смежные вопросы