#linux #malloc #alloca
#linux #malloc #alloca
Вопрос:
Почему вызов alloc( )
в качестве параметра другого вызова функции, подобного этому func(x, alloca(size), z);
, считается неправильным в соответствии с книгой под названием the linux programming interface
Это связано с тем, что пространство стека, выделенное alloca(), будет отображаться в середине пространства для аргументов функции (которые размещаются в фиксированных местах во фрейме стека). Вместо этого мы должны использовать код, подобный этому:
void *y; y = alloca(size); func(x, y, z);
хотя это неправильно
func(x, alloca(size), z); /* WRONG! */
разве эти 2 части не должны быть эквивалентными.Сначала alloca
вызывается первый, а затем func
вызывается с его возвращаемым значением, поэтому, если кто-нибудь может объяснить, как alloca
выделить память в стеке, что делает оба подхода разными.
Комментарии:
1. Есть ли какие-либо причины, почему это «неправильно»? Термины «правильный» / «неправильный» субъективны. Это «неправильно» только потому, что в одной строке есть два вызова функции, которые не соответствуют некоторому стилю кода?
2. @KamilCuk это согласно книге под названием
the linux programming interface
собираюсь отредактировать вопрос цитатой из книги
Ответ №1:
alloca
Страница руководства упоминает об этом в разделе ОШИБОК:
Во многих системах alloca() нельзя использовать внутри списка аргументов вызова функции, потому что пространство стека, зарезервированное alloca(), появится в стеке в середине пространства для аргументов функции.
Например, в func(x, alloca(1000), z);
вы могли бы закончить с макетом стека, как
sp 100c: x
sp 1008: .... space reserved by alloca
sp 8:
sp 4: sp 8 (return value of alloca())
sp 0: z
Общие ABI требуют, чтобы параметры func(void *, void *, void *)
находились в расположениях [sp 0]
, [sp 4]
и [sp 8]
. Ожидается макет, аналогичный
sp 100c: .... end of space reserved by alloca
sp c: .... space reserved by alloca
sp 8: x
sp 4: sp 0x0c (return value of alloc())
sp 0: z
Комментарии:
1. Итак, это ошибка, которая будет исправлена и не имеет ничего общего с тем, как
alloc( )
предполагается работать?2.
alloca
предполагается, что он работает путем расширения стека; нет точной спецификации, как это должно произойти. Большинство / все существующие реализации страдают от определенных (дизайнерских) ошибок (например, фактическая проблема или поведение в случае ошибки), и я бы не ожидал, что они будут исправлены. Вы должны быть осторожны, когдаalloca()
.3. Вы предполагали, что стек растет снизу? Как параметры помещаются в стек (порядок, в котором они помещаются в стек)? Не могли бы вы подробно объяснить «почему»?
4. В данном примере стек растет сверху вниз, и параметры заполняются в заданном порядке (сначала
x
, затемalloca()
, затем результатalloca()
и последнийz
).5. @ensc Но я все еще не понимаю, почему макет стека плохой (
"because the stack space reserved by alloca() would appear on the stack in the middle of the space for the function arguments."
). Компилятор не смог определить местоположение параметраz
из-за распределения выделенной памяти отsp 1008
доsp 8
?