Я изучал C- код, когда натолкнулся на следующий фрагмент:
struct example *example_clone(struct example *ex)
{
struct example *new_ex;
new_ex = ex + 1; // How does this works ?
....
new_ex = some_func(...); //makes new_ex as struct example
....
}
Теперь рассмотрим new_ex = ex + 1;
Является ли new_ex сразу после ex
в памяти?
Что делать, если какой-либо другой объект существует после ex
в памяти. Он заменен?
Функция предназначена для вызова с массивом объектов struct example
.
Например:
struct example bla[2] = { /* initializers */ };
example_clone(bla); // OK, bla[1] will be overwritten
Это нормально, так как ex + 1
указывает на существующий объект.
Но передача указателя на объект, а не на элемент массива, не в порядке:
struct example blo = { /* initializers */ };
example_clone(&blo); // Not OK, the object at &blo + 1 will be overwritten
Это не так, поскольку ex + 1
не указывает на существующий объект. Выполнение функции вызовет неопределенное поведение.
Является ли
new_ex
сразу послеex
в памяти?
Да. Он указывает на адрес памяти только за конец ex
.
Что делать, если какой-либо другой объект существует после ex в памяти. Он заменен?
Одна из двух вещей случится. Во-первых, он может перезаписать объект, который есть. Во-вторых, это может быть segfault, если эта память недоступна. По этой причине я считаю эту функцию опасной. Я бы вручную ввел этот код, чтобы вы могли проверить содержимое/существование ex + 1
.
Добавление 1
в указатель означает пункт следующего элемента. Помните, что указатели указывают на объект определенного типа (это не просто номера в памяти).
Например, если вы указываете на первый автомобиль на дворе автомобиля, то выполнение +1
означает, что вы указываете на второй автомобиль.
Если на самом деле нет другого объекта, тогда это нормально, C имеет специальный случай, когда вам разрешено указывать один за концом существующего объекта. Но если вы снова +1
это приведет к неопределенному поведению.
Если вы попытаетесь прочитать этот указатель и там нет объекта, это приведет к неопределенному поведению. Вы можете писать через указатель, пока вы записываете в память, выделенную вам.
+1
означает+ sizeof(struct example)
.ex
указывает на массив структур, тоex+1
указывает на следующую структуру в массиве. Но еслиex
указывает на одну структуру, тоex+1
не указывает ни на что полезное.