Изменение базового адреса массива

Почему я не могу изменить базовый адрес массива? Это потому, что выделенная память будет потеряна? в этом случае я могу создать массив с помощью указателя и изменить то, на что указывает указатель, и выделенная память тоже будет потеряна, тогда в чем разница?


person ASF    schedule 17.06.2019    source источник
comment
Код был скомпилирован в предположении, что вы не можете изменить базовый адрес (потому что вы не можете); он не делает предположений о том, какие глупости вы делаете с указателями на свои собственные выделения.   -  person Scott Hunter    schedule 17.06.2019
comment
Пожалуйста, отредактируйте свой вопрос и сообщите некоторую справочную информацию, чего вы хотите достичь. Что вы имеете в виду под изменением базового адреса массива? Если вы выделяете память, базовый адрес находится в выделенном блоке памяти. Изменение указателя на адрес за пределами массива приведет к неопределенному поведению при попытке доступа к данным, на которые указывает указатель.   -  person Bodo    schedule 17.06.2019
comment
Зачем вам нужно менять адрес массива?   -  person MrPromethee    schedule 17.06.2019
comment
К вашему сведению, массивы не являются указателями.   -  person Achal    schedule 17.06.2019
comment
И как бы вы это сделали? Не существует возможного синтаксиса для изменения адреса любого объекта, массива или нет.   -  person Nikos C.    schedule 17.06.2019
comment
Подумайте о доме. Адрес дома изменить нельзя, его нужно переносить с одного места на другое, по кирпичику. Массив - это объект в памяти, если вы хотите, чтобы он был в другом месте, вам нужно достаточно места в этом другом месте, а затем скопируйте туда массив.   -  person geckos    schedule 17.06.2019


Ответы (2)


Массивы сами по себе являются объектами, а не указателями. Рассмотрим более простой объект:

int a = 0;

Ожидаете ли вы, что сможете изменить его адрес? Конечно нет. Объект — это область хранения с типом. Регион хранения идентифицируется по его адресу, поэтому вы не ожидаете его изменения. И массивы тоже объекты. Когда вы объявляете

int b[8] = {0};

вы объявляете объект размером восемь целых чисел, который будет занимать некоторую память. Вы не можете изменить его адрес больше, чем вы можете изменить адрес любого отдельного int.

Вам, наверное, говорили, что массивы — это указатели. Но это не так! Чаще всего они могут быть преобразованы, даже неявно, в указатель, но они по-прежнему являются объектными типами. Указатели часто заменяют массивы, потому что адреса первого элемента достаточно, чтобы достичь любого другого элемента с помощью арифметики указателя, но указатель не является самим объектом массива. Разница становится очевидной, когда вы проверяете свойства их объектов. Например:

sizeof(b) != sizeof(int*)

Объект b не имеет размера указателя, на самом деле он имеет размер 8 целых чисел, вероятно, больше указателя.

person StoryTeller - Unslander Monica    schedule 17.06.2019
comment
Кроме того, в C нет синтаксиса для изменения адреса любого объекта. Это не значит, что вы можете изменить адрес некоторых из них, но не можете изменить адрес других. - person Nikos C.; 17.06.2019
comment
@NikosC.: Синтаксис и грамматика позволяют изменить адрес любого объекта; &b = foo; сделал бы это. Это запрещено семантикой, в частности ограничением в C 2018 6.5.16 2: «Оператор присваивания должен иметь модифицируемое lvalue в качестве левого операнда». - person Eric Postpischil; 17.06.2019
comment
@StoryTeller: Большое спасибо, но у меня есть последний вопрос, когда мы определяем параметр в функции как массив (int arr[]), можем ли мы рассматривать его как указатель? Я знаю, что когда мы передаем массив в функцию, адрес передается, но я имею в виду, что размер этого параметра не будет размером массива, и мы можем назначить любой другой массив этому параметру внутри функции. - person ASF; 19.06.2019
comment
@ASF - вы не можете определить функцию для получения массива. При объявлении `(int arr[])` компилятор уже настраивает его на указатель (int *arr). Функция может принимать только указатель. Передача массивов в качестве аргументов — это одно из мест, где происходят неявные преобразования, как я упоминал ранее. - person StoryTeller - Unslander Monica; 19.06.2019

Адреса всех переменных предварительно вычисляются на разных этапах компиляции.

В сгенерированном коде вы можете видеть, что переменный объект заменен на

Static+k for static linkage
Stack+k for automatic linkage
Reg regname
Constant hardcoded

И это могут быть другие типы адресов.

Указатель — это объект, адрес которого предварительно вычисляется, как указано выше, но значение которого может быть переменной вышеуказанного типа.

person alinsoar    schedule 17.06.2019