Перейти к содержимому

Как узнать размер массива по указателю c

  • автор:

Re: C++, можно ли узнать размер массива ?

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

ну а как в плюсах, точнее что есть в stl не знаю.

alphex_kaanoken ★★★
( 06.12.06 17:57:29 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от alphex_kaanoken 06.12.06 17:57:29 MSK

Re: C++, можно ли узнать размер массива ?

>размер можно узнать, если ты позаботился о том что последний элемент NULL, если нет, то увы но никак.
А в массиве в качестве значения NULL содержаться конечно не может.
К тому же это тогда обязательно должен быть массив указателей.

andron01
( 06.12.06 18:57:16 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от andron01 06.12.06 18:57:16 MSK

Re: C++, можно ли узнать размер массива ?

>А в массиве в качестве значения NULL содержаться конечно не может.

wtf? указатель это указатель. если у нас указатель на указатель то да нужно последним делать NULL. а в случае int* лучше держать например первым элементом количество элементов за ним замаллоченным, или отдельной переменной, не делать же лимитирующим значением 0 ?

к примеру если у меня по указателю находятся какие нить значение, например колебания того или иного, которые могут быть 0.

в случае с int[] уже выше показали как узнать.

alphex_kaanoken ★★★
( 06.12.06 19:15:01 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от aeuo 06.12.06 17:48:06 MSK

Re: C++, можно ли узнать размер массива ?

> можно если массива int arr[]

Нельзя. В списке аргументов int arr[] абсолютно равнозначно int *arr.

uj2 ★★★
( 06.12.06 20:09:13 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от uj2 06.12.06 20:09:13 MSK

Re: C++, можно ли узнать размер массива ?

> УКАЗАТЕЛЬ != МАССИВ!

int arr[5]; int *ar; ar = new int[5];

кстати где0то читал что в С массив == указатель .

anonymous
( 06.12.06 20:31:33 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от anonymous 06.12.06 20:31:33 MSK

Re: C++, можно ли узнать размер массива ?

> Забей на массивы (ибо зло) и пользуй std::vector. Там есть size().

anonymous
( 06.12.06 20:32:08 MSK )

Re: C++, можно ли узнать размер массива ?

Вот есть ещё такой немножко нестандартный подход. #include using std::cout; using std::endl; template void print(int (&arr)[Len]) < for (size_t i = 0; i < Len; ++i) cout int main() < int arr[] = ; print(arr); return 0; >

Legioner ★★★★★
( 06.12.06 21:21:23 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от Legioner 06.12.06 21:21:23 MSK

Re: C++, можно ли узнать размер массива ?

ага. и по одной функции для каждого размера =))

legk
( 06.12.06 22:30:30 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от legk 06.12.06 22:30:30 MSK

Re: C++, можно ли узнать размер массива ?

Зато компилятор может цикл развернуть, да и вообще заинлайнить всё 🙂

А так конечно vector надо пользовать.

Legioner ★★★★★
( 06.12.06 22:50:56 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от anonymous 06.12.06 20:31:33 MSK

Re: C++, можно ли узнать размер массива ?

> объясните разницу: > int arr[5]; int *ar; > ar = new int[5]; > кстати где0то читал что в С массив == указатель .

Не совсем. Имя массива это всегда указатель на ПЕРВЫЙ элемент. Например ты можешь сделать:

int *ma = malloc(5 * sizeof(int)); ma++;

shumer ★
( 07.12.06 13:05:16 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от anonymous 06.12.06 20:31:33 MSK

Re: C++, можно ли узнать размер массива ?

> объясните разницу: > int arr[5]; int *ar; > ar = new int[5]; > кстати где0то читал что в С массив == указатель . Не совсем. Имя массива это всегда указатель на ПЕРВЫЙ элемент. Например ты можешь сделать: int *ma = malloc(5 * sizeof(int)); ma++; Но нельзя: int a[] = ; a++;

shumer ★
( 07.12.06 13:06:19 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от shumer 07.12.06 13:06:19 MSK

Re: C++, можно ли узнать размер массива ?

> Имя массива это всегда указатель на ПЕРВЫЙ элемент.

Не всегда. Как раз в случаях операций ++ — sizeof x= . массив не генерирует указателя, а является немодифицируемым lvalue.

uj2 ★★★
( 07.12.06 19:50:54 MSK )
Ответ на: Re: C++, можно ли узнать размер массива ? от uj2 07.12.06 19:50:54 MSK

Re: C++, можно ли узнать размер массива ?

Вобщем, как говорил Пендальф, нужно обратиться к первоисточнику:

A7.1. Генерация указателя

Если тип выражения или подвыражения есть «массив из T», где T — некоторый тип, то значением этого выражения является указатель на первый элемент массива, и тип такого выражения заменяется на тип «указатель на T». Такая замена не делается, если выражение является операндом унарного оператора &, или операндом операций ++, —, sizeof, или левым операндом присваивания, или операндом оператора . (точка). Аналогично, выражение типа «функция, возвращающая Т», кроме случая, когда оно является операндом для &, преобразуется в тип «указатель на функцию, возвращающую T».

shumer ★
( 07.12.06 21:15:01 MSK )
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.

Похожие темы

  • Форум [C++] массивы и указатели (2010)
  • Форум [C]Подскажите как компилер обязан передавать массивы в ф-ю (2008)
  • Форум Многомерные массивы и указатели в ANSI C (2016)
  • Форум Печать массива символов. (2014)
  • Форум Сумма чисел двумерного массива во время компиляции (2018)
  • Форум bash. массивы. не понятка с размером массива. (2012)
  • Форум Ссылки на элементы массива в PHP (2012)
  • Форум Задачка с массивом строк на Си (2008)
  • Форум Странность с массивом нулевой длины в C++ (2016)
  • Форум Изменение размера массива по указателю (2018)

Как узнать размер массива по указателю c

STL использовать нельзя.

а без параметра как-то мона ? ведь как-то же память освобождается — компиллер значит знает правильный размер — обьем выделенной памяти. значит возможно и мне узнать ?

Re[3]: узнать размер массива через указатель нанего ?

От: mcf
Дата: 18.08.06 08:04
Оценка:

Здравствуйте, Аноним, Вы писали:

А>STL использовать нельзя.

А>а без параметра как-то мона ? ведь как-то же память освобождается — компиллер значит знает правильный размер — обьем выделенной памяти. значит возможно и мне узнать ?

Это не компилятор знает, а ОС.

Re[3]: узнать размер массива через указатель нанего ?

От: bkat
Дата: 18.08.06 08:05
Оценка: 2 (2)

Здравствуйте, Аноним, Вы писали:

А>STL использовать нельзя.

А>а без параметра как-то мона ? ведь как-то же память освобождается — компиллер значит знает правильный размер — обьем выделенной памяти. значит возможно и мне узнать ?

STL использовать нельзя, а грязные хаки значить можно?
Странная однако философия.
Лучше передавай размер как 2-й параметр.
Ну или напиши облегченный аналог std::vector без возможности
динамически добавлять/удалять элементы.

Re: узнать размер массива через указатель нанего ?

От: mcf
Дата: 18.08.06 08:05
Оценка: -2

Здравствуйте, oncer, Вы писали:

O>есть такой код примерно:
O>

 O>void SomeMethod(int* pArray) O> < O>//как здесь узнать количество элементов в масиве на который указывает pArray ? O> //pArray length - ? O>> O>. O>int* pArray = new int[5]; O>SomeMethod(pArray); O>. O>

Можно и так передавать.

void SomeMethod(int pArray[5])

Re[2]: узнать размер массива через указатель нанего ?

От: Master Yoda
Дата: 18.08.06 08:30
Оценка:

Здравствуйте, mcf, Вы писали:

mcf>Можно и так передавать.
mcf>

mcf>void SomeMethod(int pArray[5]) mcf>

Это то же самое, что и:

void SomeMethod(int* pArray)

можешь поискать по форуму, это обсуждалось

Передать размер можно разве что так:

templateclass T, int N> void SomeMethod(T(&arr)[N]) < // . >

It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[3]: узнать размер массива через указатель нанего ?

От: nen777w
Дата: 18.08.06 08:36
Оценка:

А>а без параметра как-то мона ? ведь как-то же память освобождается — компиллер значит знает правильный размер — обьем выделенной памяти. значит возможно и мне узнать ?

Некоторые компиляторы при выделении памяти отводят в начале четыре байта для записи туда размера выделенного блока.
оператор delete читает эти данные.
Но тут ИМХО всё от компилятора зависит и от того как перегружен new.

Если сильно так нужно то как вариант можно перегрузить оператор new и delete.

Re[3]: узнать размер массива через указатель нанего ?

От: bkat
Дата: 18.08.06 08:43
Оценка: +1

Здравствуйте, Master Yoda, Вы писали:

MY>Передать размер можно разве что так:

MY>

MY>templateclass T, int N> MY>void SomeMethod(T(&arr)[N]) MY> < MY>// . MY>> MY>

Для динамических массивов, создаваемых с помощью new это лишено смысла.

Re: узнать размер массива через указатель нанего ?

От: Centaur
Дата: 18.08.06 09:46
Оценка: 1 (1) +2

Здравствуйте, oncer, Вы писали:

O>есть такой код примерно:
O>

O>void SomeMethod(int* pArray) O> < O>//как здесь узнать количество элементов в масиве на который указывает pArray ? O> //pArray length - ? O>> O>. O>int* pArray = new int[5]; O>SomeMethod(pArray); O>. O>

Портабельно — никак. Стандартная идиома C — передавать размер массива вместе с указателем на начало:

void SomeMethod(int* pArray, size_t size) < for (size_t i = 0; i < size; ++i) < pArray[i] = i * 2; >> … int* pArray = malloc(5 * sizeof(int)); SomeMethod(pArray, 5); free(pArray); pArray = NULL;

Стандартная идиома C++ — передавать пару итераторов [first, last):

template typename Iterator> void SomeMethod(Iterator first, Iterator last) < for (; first != last; ++first) < *first = i * 2; >> … int* pArray = new int[5]; SomeMethod(pArray, pArray + 5); delete[] pArray; pArray = 0;

Re[3]: узнать размер массива через указатель нанего ?

От: _DAle_
Дата: 18.08.06 10:38
Оценка:

Здравствуйте, Аноним, Вы писали:

А>STL использовать нельзя.

А>а без параметра как-то мона ? ведь как-то же память освобождается — компиллер значит знает правильный размер — обьем выделенной памяти. значит возможно и мне узнать ?

Автор: Андрей Тарасевич
Дата: 15.07.02
Re[4]: узнать размер массива через указатель нанего ?

От: Кодт
Дата: 18.08.06 11:25
Оценка: 3 (3)

Здравствуйте, mcf, Вы писали:

А>>а без параметра как-то мона ? ведь как-то же память освобождается — компиллер значит знает правильный размер — обьем выделенной памяти. значит возможно и мне узнать ?
mcf>Это не компилятор знает, а ОС.

Это не компилятор и не ОС.

Выражение new[] возвращает указатель на первый элемент массива, а не на начало блока памяти .
Для тех случаев, когда у элементов есть нетривиальные деструкторы — в начало блока записывается длина массива, с тем, чтобы delete[] мог корректно их поубивать перед освобождением. Если же деструкторы тривиальны — то информация о длине не нужна.
Но всё это, включая хранение/измерение и размера блока, и длину массива — implemenation-defined и пользователю недоступно.
К примеру, в ANSI C прописаны функции

void* malloc(size_t); void free(void*); void* realloc(void*,size_t); //которые, конечно же, внутри себя знают размеры блоков. а наружу это можно получить, например, в MS-specific функции size_t _mbsize(void*); //для которой выполняется неравенство assert( _mbsize(malloc(n)) >= n );

Перекуём баги на фичи!
Re[5]: узнать размер массива через указатель нанего ?

От: Аноним
Дата: 13.11.06 15:27
Оценка:

Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, mcf, Вы писали:

А>>>а без параметра как-то мона ? ведь как-то же память освобождается — компиллер значит знает правильный размер — обьем выделенной памяти. значит возможно и мне узнать ?
mcf>>Это не компилятор знает, а ОС.

К>Это не компилятор и не ОС.

К>Выражение new[] возвращает указатель на первый элемент массива, а не на начало блока памяти .
К>Для тех случаев, когда у элементов есть нетривиальные деструкторы — в начало блока записывается длина массива, с тем, чтобы delete[] мог корректно их поубивать перед освобождением. Если же деструкторы тривиальны — то информация о длине не нужна.
К>Но всё это, включая хранение/измерение и размера блока, и длину массива — implemenation-defined и пользователю недоступно.

Полностью согласен. контретизируя, можно использовать на свой страх и риск

SomeType* pArray = NULL; GetArray(pArray); cout 

Re: узнать размер массива через указатель нанего ?

От: alex012
Дата: 13.11.06 16:38
Оценка:

Здравствуйте, oncer, Вы писали:

Возможно так подойдет:

#include #include using namespace std; void main() < const size_t nSize = 5; int* nArray = new int[nSize]; cout sizeof(int)

Как sizeof вычисляет размер массива?

Как sizeof вычисляет размер массива, если передавая функции имя массива, по факту передается указатель на первый элемент, в данном случае sizeof получает указатель на int (sizeof (int) == 4). Откуда функция узнает количество элементов? По идеи при передаче sizeof указателя, должен возвращаться размер этого указателя (в моем случае 8).
sizeof(&arr[0]) == 8.
Как это все работает если // &arr[0] == arr
Выводят один и тот же адрес:

printf("%p\n", &arr[0]); printf("%p\n", arr);

А вот если вызывать sizeof с этими значениями то будет разные результаты.

printf("%zd\n", sizeof(&arr[0])); // Выводится размер указателя printf("%zd\n", sizeof(arr)); // Выводится размер всего массива, хотя и то и то являются адресами первого элемента
  • Вопрос задан более трёх лет назад
  • 9185 просмотров

Комментировать
Решения вопроса 0
Ответы на вопрос 1
Developer, ex-admin

sizeof - это не функция (хоть и выглядит похоже) - это операция взятия размера.
sizeof всегда вычисляется на этапе компиляции, т.е. в исполняемом файле вместо вызова sizeof уже будет вычисленная константа.
Когда компилятор знает размер массива, как в вашем примере, он вернет полный размер массива.
Но если передать в sizeof произвольный указатель (именно указатель, а не статический массив), он вернет размер указателя.

Статический массив - это не указатель. Указатель - на этапе выполнения занимает в памяти место для хранения адреса. Статический массив занимает в памяти место для хранения данных массива.
Поэтому статический массив - это не указатель. Хотя часто компилятор работает с именем статического массива как с указателем.

Ответ написан более трёх лет назад
Нравится 19 8 комментариев
dandropov95 @dandropov95 Автор вопроса

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

CityCat4

Имя массива не часто - оно всегда является указателем на первый элемент. Но Вас запутало то, что sizeof - не функция. sizeof -это число 🙂 Его аргументом являются только полностью определенные типы, поэтому еще на этапе компиляции sizeof(arr) превратится в sizeof(int) * SIZE. А вот sizeof(*(arr + 0)) - это явный запрос адреса, то есть если перевести на "человеческий" это будет - "хочу узнать размер ячейки, в которой записан адрес элемента arr+0"

Как определить длину массива в C++

По сути, когда мы говорим о длине массива, мы имеем в виду общее количество элементов, присутствующих в соответствующем массиве. Например, посмотрите на массив ниже:

int array1[] =

Размер (или длина) массива равна общему количеству элементов в нем. Следовательно, в данном случае это «5».

Способы определения длины массива в C++

Теперь давайте посмотрим на различные способы, с помощью которых мы можем выяснить длину массива в C++:

  • поэлементный подсчет,
  • begin() и end(),
  • функция sizeof(),
  • функция size() в STL,
  • указатели.

Теперь давайте обсудим каждый метод подробно и с примерами.

1: Поэлементный подсчет

Самый очевидный способ – перебрать заданный массив и одновременно подсчитать общее количество перебранных элементов.

Но если мы заранее не знаем длину массива для итерации, то в таком случае мы не можем использовать цикл for. Эту проблему можно решить, используя простой цикл for-each. Внимательно посмотрите на приведенный ниже код.

#include #include using namespace std; int main() < int c; int arr[]=; cout cout

Вы получите такой результат:

The array is: 1 2 3 4 5 6 7 8 9 0 The length of the given Array is: 10

Как мы говорили выше, здесь мы перебираем весь массив arr, используя цикл for-each с итератором i. Значение счетчика c увеличивается по мере итерации. Когда перебор закончится, в c вы найдете длину данного массива.

2: Функции begin() и end()

Мы также можем вычислить длину массива, используя стандартные функции begin() и end(). Эти две функции возвращают итераторы, указывающие на начало и конец массива соответственно. Внимательно посмотрите на данный код:

#include #include using namespace std; int main() < //Given Array int arr[] = < 11, 22, 33, 44 >; cout

Следовательно, разница между возвращаемыми значениями двух функций end() и begin() дает нам размер или длину данного массива. Данный код вернет:

The Length of the Array is : 4

3: Функция sizeof()

Оператор sizeof() в C++ возвращает размер переданной переменной или данных в байтах. Кроме того, он возвращает общее количество байтов, необходимых для хранения массива. Следовательно, если мы просто разделим размер массива на размер, занимаемый каждым его элементом, мы узнаем общее количество элементов, присутствующих в массиве.

Давайте посмотрим, как это работает:

#include #include using namespace std; int main() < //Given array int arr[] = ; int al = sizeof(arr)/sizeof(arr[0]); //length calculation cout

В результате мы получим:

The length of the array is: 3

4: Функция size() в STL

В стандартной библиотеке есть функция size(), которая возвращает количество элементов в заданном контейнере (в нашем случае это массив).

#include #include using namespace std; int main() < //Given array arrayarr< 1, 2, 3, 4, 5 >; //Using the size() function from STL cout

В результате вы получите:

The length of the given Array is: 5

5: Определение длины массива с помощью указателей

Узнать длину массива можно с помощью указателей. Давайте посмотрим, как это делается:

#include #include using namespace std; int main() < //Given array int arr[6] = ; int len = *(&arr + 1) - arr; //*(&arr + 1) is the address of the next memory location // just after the last element of the array cout

В результате мы получим:

The length of the array is: 6

Выражение *(arr+1) выдает адрес области памяти сразу после последнего элемента массива. Следовательно, разница между ним и начальным местоположением массива (или базовым адресом, arr) показывает общее количество элементов, присутствующих в данном массиве.

Заключение

Итак, в этом мануале мы обсудили различные методы определения длины массива в C++. Все приведенные выше методы просты в использовании, однако мы предпочитаем применять цикл for-each – не только из-за удобочитаемости кода, но и из-за его кросс-платформенной надежности.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *