проблема с оператором sizeof - PullRequest
4 голосов
/ 23 января 2011

Поскольку я хочу динамически находить размер массива в функции, я использовал оператор sizeof.Но я получил неожиданный результат.Вот одна демонстрационная программа, чтобы показать вам, что я хочу сделать.

//------------------------------------------------------------------------------------------
#include <iostream>

void getSize(int *S1){

    int S_size = sizeof S1/sizeof(int);
    std::cout<<"array size(in function):"<<S_size<<std::endl;
}

int main(){

    int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
    getSize(S);
    std::cout<<"array size:"<<sizeof S/sizeof(int)<<std::endl;
    return 0;
}
//------------------------------------------------------------------------------------------

команда компиляции: g ++ demo1.cc -o demo1 {fedora 12}

вывод:

array size(in function):2
array size:19

объясните, пожалуйста, почему это происходит.что можно сделать, чтобы решить эту проблему.

Ответы [ 6 ]

9 голосов
/ 23 января 2011
void getSize(int *S1)

Когда вы передаете массив этой функции, он распадается на тип pointer , поэтому оператор sizeof вернет размер указателя.

Однако вы определяете свою функцию как

template<int N>
void getSize(int (&S1)[N])
{
   //N is the size of array
   int S_size1 = N;
   int S_size2 = sizeof(S1)/sizeof(int); //would be equal to N!!
   std::cout<<"array size(in function):"<<S_size1<<std::endl;
   std::cout<<"array size(in function):"<<S_size2<<std::endl;
}

int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
getSize(S); //same as before

тогда вы можете иметь размер массива в функции!

Смотрите демонстрацию самостоятельно здесь: http://www.ideone.com/iGXNU

3 голосов
/ 23 января 2011

Внутри getSize() вы получаете размер указателя, который составляет 8 байт (поскольку вы, вероятно, используете 64-разрядную ОС).В main() вы получаете размер массива.

Если вы хотите узнать размер массива, передайте результат sizeof(S) в качестве дополнительного аргумента getSize().

Больше альтернативиспользовать какой-нибудь контейнер (например, std::vector) или превратить функцию в функцию шаблона, как предложил Наваз.

0 голосов
/ 23 января 2011

Чтобы предотвратить случайное неправильное использование sizeof, вы можете определить функцию, которая работает только с массивами:

template<class T, int N>
int array_size(T (&)[N]) {
  return N;
}

Если вы используете это в своем коде, вы увидите ошибку компилятора при применениина S1, так как это не массив.Кроме того, он короче и немного более явный, чем sizeof array / sizeof array [0] (использование размера первого элемента означает, что вам не нужно повторять тип массива).

Это также уже существует вПовысьте в более общем виде (принимая что-либо с помощью метода размера, такого как std :: vector).

0 голосов
/ 23 января 2011

S - это int *, указатель на целое число, которое является адресом памяти, который на вашей машине в два раза больше целого числа.

Если вам нужен размер массива (т. Е. Количество элементов), вы не можете получить его непосредственно в чистом C. Но, поскольку это вопрос c ++, есть способ: использовать vector, который имеет size() метод.

На самом деле, это не совсем так: внутри функции , которую вы объявляете S (и только если она явно инициализируется во время компиляции, как вы делаете в своем примере - даже new int[19] не делает не работает), оператор sizeof действительно получает правильный ответ, поэтому c ++ позволяет вам сделать это:

int S[]={1,2,3,2,5,6,25,1,6,21,121,36,1,31,1,31,1,661,6};
vector<int> v(S, S + sizeof(S) / sizeof(int) );

и затем вы можете использовать v.size() (см. эти документы ).

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

0 голосов
/ 23 января 2011

Вам нужно передать размер массива функции.

Поскольку вы передаете указатель только на первый элемент в массиве, ваша функция не имеет информации о его реальном размере.

void getSize(int *S1, size_t size)
{
    int S_Size = sizeof(*S1) * size;
}

Это избыточно, если подумать: D

0 голосов
/ 23 января 2011

вы получаете размер указателя на массив.Если вам нужен размер массива, вы должны умножить количество элементов на размер каждого элемента.

...