2015-02-19 2 views
-2
class Class1 
{ 
    int data; 
    int *dataPtr; 
} 

int main() 
{ 
    Class1 object; 
    Class1 *objectPtr = &object; 
    object.data = 1100; 
    object.dataPtr = &(object.data) 

    std::cout << object.dataPtr << std::endl; //0x22aaa4 
    std::cout << (void *) (object.data) << std::endl; //0x1b198 
    std::cout << (void *) &(object.data) << std::endl; //0x22aaa4 

Почему (void *) (object.data) отличается от object.dataPtr?Почему указатель void отличается от значения ссылки?

, если я хочу скопировать значение из другого места в object.data с помощью memcpy, в какую ячейку памяти я использую?

memcpy((void *) (object.data), source, size); или

memcpy((void *) &(object.data), source, size);

Спасибо!

+3

Один конвертирование целого числа в ничтожном *, один вы получите адрес этого целого. – BWG

+2

Я не вижу здесь никаких ссылок. –

+1

Этот вопрос невероятно запутан. Для начала вы никогда не используете 'objectPtr'. Во-вторых, это недействительно C++. –

ответ

3

Потому что (void *) (object.data) переинтерпретирует числовое значение data в качестве указателя, чтобы оно могло иметь любое значение; и что-то с ним приводит к неопределенному поведению. (Как отмечено в комментариях, можно было бы ожидать, что оно будет 0x44c, если конкретный реализатор просто использует числовое значение 1100 в качестве адреса, а неопределенное поведение не вызывает каких-либо неожиданностей.)

Адрес object.data является &object.data.

Если вы использовали более безопасный бросок или, в случае memcpy, неявного преобразования, то компилятор будет препятствовать ускользающее преобразование:

static_cast<void *>(object.data) // ERROR: int->pointer conversion 
static_cast<void *>(&object.data) // OK: pointer conversion 

memcpy(object.data, source, size); // ERROR: int where pointer expected 
memcpy(&object.data, source, size); // OK: pointer converts to void* 

В общем, избежать C-стиле бросает. И memcpy. И указатели.

+0

Нет, (void *) (object.data) не может иметь значения, он должен be 0x00044c, которое является числовым значением 1100. И, фактически, это именно то значение, которое оно имеет, если вы исправляете ошибки в размещенном фрагменте кода и запускаете его. (Как я и сделал для моего ответа.) –

+0

@MikeNakis: Преобразование определяется реализацией, и использование его - неопределенное поведение, поэтому оно может иметь любое значение. Хотя я не заметил, что оно было настроено на определенную ценность; вы правы, что это самая вероятная ценность. –

+0

Спасибо за ваше объяснение, теперь это имеет смысл. Это был псевдо-код для представления фактического кода. Фактический код имел 'object.data = 111000;' поэтому он выводит 0x1b198. Я не понимал, что это было шестнадцатеричное значение, когда я разместил это. – user4584454

0

Этот вопрос является фиктивным. Код даже не будет компилироваться без первых синтаксических ошибок.

Как только вы его скомпилируете, производит точно ожидаемый результат, а не то, что говорит OP.

Здесь: http://ideone.com/qXWkGF

Success time: 0 memory: 3096 signal:0 
0xbfbd5888 
0x44c 
0xbfbd5888 
+0

Извините, я имел в виду, что это псевдо-код. Фактический код делает что-то похожее на то, что я разместил, но для простоты мне просто нужен костяной код. – user4584454