2016-12-01 3 views
-1

Рассмотрим следующий код в C:Невозможно определить размер массива указателей

int size = sizeof(a)/sizeof(a[0]) 

a имеет тип char ** и его цель моего кода в виде массива. Гарантируется, что a имеет несколько элементов. Так или иначе, size всегда получает значение 1.

Мое первоначальное предположение состоит в том, что a в sizeof(a) обрабатывается как первый указатель вместо массива. Как это исправить?

+1

'a' не является массивом. – immibis

+0

'a' - указатель. Его размер - это размер указателя 'char **'. Как комментирует [@immibis] (http://stackoverflow.com/questions/40902677/unable-to-determine-the-size-of-an-array-of-pointers#comment69018980_40902677), это не массив. – chux

ответ

1

С помощью указателя вы не можете знать размер буфера/массива, на который он указывает. Вы всегда должны отслеживать/передавать размер массива самостоятельно.

Уловка, которую вы пытаетесь использовать, относится только к массивам (которые деградируют до указателей). К сожалению, его можно случайно применить к указателям. Поэтому ядро ​​Linux определяет следующий макрос:

#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]) + __must_be_array(arr)) 

http://lxr.free-electrons.com/source/include/linux/kernel.h#L53

__must_be_array() вызывающую некоторые компилятором конкретные функциональные возможности для обеспечения ошибки вы только что сделали вызывает ошибку компиляции, вместо неправильного значения.

0

У вас нет. Только с массивами (переменные, объявленные квадратными скобками, например char x[80]) сделают это правильно. Невозможно определить размер области указателем (переменная с объявлением со звездочкой, например char *y) указывает на. Если вы передаете массив в функцию, функция либо должна уже знать размер, либо вам нужно передать размер с помощью указателя.

Так что происходит в вашем примере: sizeof(a) - размер указателя (для указателя на символ) в архитектуре вашего процессора; скорее всего 8. sizeof(a[0]) - размер указателя (для символа) - все еще 8, так как размер указателя - размер указателя, независимо от того, на что они указывают. Невозможно продвинуть указатель на массив (хотя легко перейти в другом направлении и назначить массив указателю).