2012-10-10 3 views
0

Итак, на тесте у меня был этот вопрос задал:Каков адрес памяти этого указателя?

int* ptrA; // assigned memory address 100 
int a = 1; // assigned memory address 600 
ptrA = &a; 

What is the memory address of ptrA + 2? 

Я думал, что это было 606 (int 4 байта + в адрес a, который 600 + 2 = 606, но, по-видимому, ответ был 608, что я пропущу, чтобы сделать это правдой?

+6

Если это, как был сформулирован тест вопрос, тест отстой. –

+3

Я очень сомневаюсь, что это то, что на самом деле было задано на тест ... по крайней мере там было бы «PtrA = & a». –

+0

@Jim: если вопрос не был умышленно проверен, что такая ошибка была замечена учеником .... –

ответ

5

Это неопределенное поведение, выражение PtrA + 2 является незаконным. Вы можете выполнять арифметику указателей только по указателям, которые у вас есть, и не можете добавлять или вычитать указатели/вне указателей вне диапазона массива вы владеете или выходите за пределы диапазона.

Мы можем все еще анализируют это (хотя и бесполезно, из-за UB). Вы принимаете адрес a: 600 + 2, но это не так, поскольку, возможно, sizeof(int*) также является 4, поэтому это будет 600 + 4. Таким образом, вы получаете 600 + 4 + 4 = 608.

+0

Я немного смущен, как +2 превратился в +4. Например, если вопрос был «ptrA + 10», это было бы 600 + 4 + 10 = 614? –

+2

@Howdy_McGee Это может показаться противоречивым, но добавление 2 в 'int *' перемещает адрес _two ints_, а не _two bytes_. Поскольку int имеет ширину 4 байта, вы фактически добавляете 8 байт к исходному адресу. –

+0

UB в стороне, существуют ли какие-либо архитектуры реального мира, где арифметика указателя с недействительными указателями не работает? (при условии, что вы никогда не разыскиваете недействительные указатели, конечно) –

0

В C/C++ арифметика указателя использует размер объекта, на который указывает указатель. Пример:

int* PtrA = (int*)600; 

Значение PtrA+2 будет 608 при условии, что размер целого числа равно 4.

Стандарт позволяет делать арифметические операции над указателями только внутри массивов или «сразу после массива». Это означает, что необходимо соблюдать определенную осторожность.

3

Фактически Арифметические операции с указателями различны. Они увеличиваются в зависимости от размера типа данных, поэтому, если задан один адрес, скажите x и u попросите x + 2 .. (если x является целым указателем), то ..

x + 2 означает ---- x + (SizeOf (INT)) * 2

если х задается как символ указателя затем

х + 2 означает ---- х + (SizeOf (Char)) * 2

Спасибо.

+0

Я говорю, что это будет sizeof (int *) или sizeof (char *). Оба эти размера одинаковы. Это sizeof (int) или sizeof (char) – auny

+0

@auny: yeah ur correct .. отредактировал сейчас .. спасибо –

+0

Хороший ответ ................ :) – vikky

1

В С, x + y где x - указатель, эквивалентный &x[y]. Предположим, что у вас

int abc[3] = {1,2,3}; 
int* ptr = &abc[0]; 

&ptr[2] (ptr + 2) является адрес 3, что явно 8 больше, чем адрес 1.

+0

"явно еще 8 ..." Нет, это не так, пока вы ничего не скажете о 'sizeof (int)' –

+0

@EmilioGaravaglia OP написал «int is 4 bytes», другой swers, включая принятый ответ, основаны на этом понимании. –

1
int* PtrA; // assigned memory address 100 
int a = 1; // assigned memory address 600 

What is the memory address of ptrA + 2? 

Вопрос неоднозначный.

Если вопрос: «Что такое (адрес памяти ptrA) + 2?», То вы сказали, что ptrA находится по адресу памяти 100 (игнорируя PtrA! = PtrA) и добавляя 2 к указателю в C и C++ увеличивает значения в кратных размерах заостренного типа, поэтому, если int - 32 бита, тогда конечный результат равен 100 + 2 * 4 = 108.

Если вопрос: «Каков адрес памяти (ptrA + 2)? ", Что означает результат добавления значения в переменную ptrA и 2, тогда это не определено, поскольку не показана инициализация ptrA, и это неопределенное поведение, чтобы попытаться прочитать из неинициализированной памяти.

Ваши ожидания и предполагаемый ответ предложить предполагаемый код был ...

ptrA = &a; 

... когда-нибудь до того, как ptrA + 2 должна была быть оценена. Если это так, то ответ будет 600 + 2 * sizeof(int), который, скорее всего, будет 608.

+0

+1 для чистого описания двусмысленности в вопросе, который показывает неграмотность автора теста. Цель испытаний должна заключаться в том, чтобы доказать знание, а не выдавать ловушки, которые не могут быть поняты, чтобы обманывать неправильные ответы (особенно, когда любой ответ может быть правдой ложным, возвращая смысл вопросов!) –

0

Я думаю, это неправда, что адреса всегда будет больше. Это может быть и меньше. Мы уверены, что ptr является указателем на базовый адрес массива a целых чисел, тогда ptr + 2 укажет на 3-й элемент массива. Поэтому, если базовый адрес массива равен 600, тогда адрес может быть 600 + 2 * (sizeofIint)) или может быть 600-2 * sizeof (int); Но в любом случае он укажет на третий элемент этого массива. Поэтому я считаю, что даже в случаях массивов мы не должны полагаться на прямые адреса. и не должны делать никаких предположений о том, будет ли ptr + 2 указывать на 608 или что-то еще.

Благодарности & С уважением, Саурабх

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