Как найти размер динамического массива

Code for dynamic array by entering size and storing it into «n» variable, but I want to get the array length from a template method and not using «n».

int* a = NULL;   // Pointer to int, initialize to nothing.
int n;           // Size needed for array
cin >> n;        // Read in the size
a = new int[n];  // Allocate n ints and save ptr in a.
for (int i=0; i<n; i++) {
    a[i] = 0;    // Initialize all elements to zero.
}
. . .  // Use a as a normal array
delete [] a;  // When done, free memory pointed to by a.
a = NULL;     // Clear a to prevent using invalid memory reference.

This code is similar, but using a dynamic array:

#include <cstddef>
#include <iostream>
template< typename T, std::size_t N > inline
std::size_t size( T(&)[N] ) { return N ; }
int main()
{
     int a[] = { 0, 1, 2, 3, 4, 5, 6 };
     const void* b[] = { a, a+1, a+2, a+3 };
     std::cout << size(a) << 't' << size(b) << 'n' ;
}

The sizeof operator works at compile time, except for the case when the operand is variable length array, and the dynamic memory allocation is run time operation.
In the expression:

printf("%d  %d",sizeof(RandomArray),sizeof(*RandomArray));

the type of RandomArray is int * and the type of *RandomArray is int.

Hence, the expression is equivalent to:

printf("%d  %d",sizeof(int *),sizeof(int));

for which the sizeof will yield the result as an integer constant and therefore, you will get the same result every time irrespective of the size of memory allocate to RandomArray.

How to find the size of dynamic array

Keep the track of the size from the point where you are allocating memory dynamically.


Beware, you are multiplying the value returned by rand()%11 to the sizeof *RandomArray while allocating memory and rand() may return 0 as well which will lead to malloc(0). Good to know that (from C Standards#7.22.3):

….If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.

NelLy0892

-15 / 0 / 4

Регистрация: 27.10.2015

Сообщений: 228

1

Узнать размер динамического массива

23.11.2016, 14:01. Показов 21598. Ответов 4

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Здравствуйте. Пытаюсь сделать динамический массив и вывести его размерность. Выводится размерность = 4, подскажите пожалуйста где я накосячила?

C++
1
2
3
4
5
6
7
8
9
10
11
#include <stdlib.h>
#include <stdio.h>
int main()
{
    char* s = new char[256];
    printf("enter anything n");
    scanf("%s", s);
    printf("size of massiv= %d", sizeof(s));
    system("PAUSE");
    return 0;
}



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

23.11.2016, 14:01

4

17410 / 9246 / 2260

Регистрация: 30.01.2014

Сообщений: 16,169

23.11.2016, 14:40

2

Лучший ответ Сообщение было отмечено tezaurismosis как решение

Решение

Цитата
Сообщение от NelLy0892
Посмотреть сообщение

Выводится размерность = 4,

sizeof() работает на этапе компиляции и выводит размер на основе статической информации о типе. В данном случае тип — это указатель, в твоем компиляторе указатель имеет размер 4.

Размер динамически выделенной памяти переносимым, безопасным и (самое главное) стандартным путем узнать нельзя.
В месте выделения памяти ты размер знаешь, вот и храни его рядом с указателем.



1



-15 / 0 / 4

Регистрация: 27.10.2015

Сообщений: 228

30.11.2016, 11:39

 [ТС]

3

я не поняла совет



0



Диссидент

Эксперт C

27488 / 17175 / 3784

Регистрация: 24.12.2010

Сообщений: 38,685

30.11.2016, 13:02

4

Лучший ответ Сообщение было отмечено tezaurismosis как решение

Решение

Цитата
Сообщение от NelLy0892
Посмотреть сообщение

не поняла

Ты же сама выделяешь память. Вот сама и храни этот выделенный размер в своей переменной. Рядом-не рядом — это уже дело десятое.
И, как правильно заметил предыдущий оратор, s — это указатель. sizeof(s) — это размер указателя
А зачем тебе какими-то ухищрениями узнавать размер выделенной памяти? Ту же его знаешь (и я знаю, глядя на твой код) — 256
Практически повторяю сказанной в посте 2, но иногда от изложения другими словами смысл доходит лучше



0



-15 / 0 / 4

Регистрация: 27.10.2015

Сообщений: 228

30.11.2016, 14:05

 [ТС]

5

теперь поняла, спасибо



0




Форум программистов Vingrad

Модераторы: bsa

Страницы: (4) Все [1] 2 3 … Последняя »
( Перейти к первому непрочитанному сообщению )

Поиск:

Ответ в темуСоздание новой темы
Создание опроса
> Узнать размер динамического массива 

:(

   

Опции темы

TheDestroyer
Дата 2.4.2009, 13:04 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2007

Репутация: нет
Всего: нет

Возможно ли узнать размер динамического массива?

Код

int *ar;    // указатель на элемент массива
int size=100;

ar=new int[size];        //Выделение памяти
memset(ar,0,size);    //Инициализация
size = sizeof(ar); // выдает 4

delete[] ar;            //Удаление

Похоже, что размер динамического массива узнать в C++, (у меня Borland C++) невозможно, и надо каждый раз передавать его размер как параметр. Это так?
Спасибо

PM MAIL   Вверх
Alca
Дата 2.4.2009, 13:07 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50

Цитата
невозможно

Возможно если массив это сишная строка

Код

strlen(size);

Добавлено через 34 секунды
В других случаях надо передавать размер массива.

Добавлено через 1 минуту и 5 секунд

Цитата

Код

size = sizeof(ar); // выдает 4

Это размер указателя

———————

C++ cross-platform library

PM WWW ICQ Skype Jabber   Вверх
zim22
Дата 2.4.2009, 13:14 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

depict1
****

Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69

Цитата(TheDestroyer @  2.4.2009,  13:04 Найти цитируемый пост)
 и надо каждый раз передавать его размер как параметр

один из способов избежать передачи размера в качестве отдельного параметра заключается в передачи пары итераторов на начало массива и на элемент после его конца.
ещё один способ: последний элемент массива инициализировать значением-флагом, при достижении которого вы завершите итерировать его элементы. 

Это сообщение отредактировал(а) zim22 — 2.4.2009, 13:20

———————

C++ FAQ Lite

PM MAIL   Вверх
Dmi3ev
Дата 2.4.2009, 13:14 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 13
Всего: 41

Цитата
size = sizeof(ar);

когда ты так пишешь ты должен понимать, что ar — это не массив, это всего лишь указатель… и размер массива массива ( 1 или 1000 элементов) никак не касается указателя…
а если ты хочешь узнать объем в байтах, то можно просто после выделения памяти посчитать

Код

int *ar;    // указатель на элемент массива
int size=100;
ar=new int[size];        //Выделение памяти
memset(ar,0,size);    //Инициализация
int size1=sizeof(int)*size;
delete[] ar;  

Это сообщение отредактировал(а) Dmi3ev — 2.4.2009, 13:14

———————

PM MAIL   Вверх
Alca
Дата 2.4.2009, 13:22 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50

заверни свои данные в структуру и передавай ее в функцию

Это сообщение отредактировал(а) Alca — 2.4.2009, 13:22

———————

C++ cross-platform library

PM WWW ICQ Skype Jabber   Вверх
zim22
Дата 2.4.2009, 13:22 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

depict1
****

Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69

Цитата(Dmi3ev @  2.4.2009,  13:14 Найти цитируемый пост)
int size1=sizeof(int)*size;

Гугл рекомендует не использовать sizeof от типа.
лучше написать 

Код

int size1=sizeof(size)*size;

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

———————

C++ FAQ Lite

PM MAIL   Вверх
mes
Дата 2.4.2009, 13:37 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

любитель
****

Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250

Цитата(zim22 @  2.4.2009,  12:14 Найти цитируемый пост)
один из способов избежать передачи размера в качестве отдельного параметра заключается в передачи пары итераторов на начало массива и на элемент после его конца.
ещё один способ: последний элемент массива инициализировать значением-флагом, при достижении которого вы завершите итерировать его элементы. 

еще один : использовать std::vector и отградить себя от рутинной работы по контролю за динамическим массивом. smile

———————

http://opendots.net

PM MAIL WWW   Вверх
azesmcar
Дата 2.4.2009, 13:39 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

uploading…
****

Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211

Цитата
ещё один способ: последний элемент массива инициализировать значением-флагом, при достижении которого вы завершите итерировать его элементы. 

а может лучше в первом байте хранить размер и не считать в таком случае smile

Код

template <class T>
T* newArray(size_t count) {
    T* r = new T[count + 1];
    r[0] = count;
    return ++r;
}

template <class T>
void deleteArray(T* p) {
    delete [] --p;
}

template <class T>
int sizeofArray(T* p) {
    return *(p - 1);
}

что-то вроде этого

PM   Вверх
mrbrooks
Дата 2.4.2009, 13:39 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

трололомен
****

Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 19
Всего: 306

TheDestroyer, используй std::vector и не ломай мозг.

PM MAIL   Вверх
mrbrooks
Дата 2.4.2009, 13:40 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

трололомен
****

Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

Репутация: 19
Всего: 306

mes, припозднился  smile 

PM MAIL   Вверх
azesmcar
Дата 2.4.2009, 13:40 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

uploading…
****

Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211

по любому у этих методов полно недостатков, лучше передавать..либо в структуре, либо просто так..без разницы

Добавлено через 2 минуты и 3 секунды
а еще лучше — как сказали 
mrbrooks
mes используй вектор

PM   Вверх
Anikmar
Дата 2.4.2009, 13:47 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 5
Всего: 59

Цитата(mes @  2.4.2009,  13:37 Найти цитируемый пост)
еще один : использовать std::vector и отградить себя от рутинной работы по контролю за динамическим массивом.

Если это массив собственных классов — попутно наградить себя определением соответствующих конструкторов и операторов smile 

PM MAIL ICQ   Вверх
zim22
Дата 2.4.2009, 13:47 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

depict1
****

Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69

Цитата(TheDestroyer @  2.4.2009,  13:04 Найти цитируемый пост)
Возможно ли узнать размер динамического массива?

размер статических массивов неявно передаётся в функцию в качестве параметра

Код
template <typename T, size_t size>
size_t get_size(const T (&arr)[size]) {
  return size;
}
int _tmain(int argc, _TCHAR* argv[])
{
  int arr[25];
  size_t size = get_size(arr);
    return 0;
}

———————

C++ FAQ Lite

PM MAIL   Вверх
ISergeyN
Дата 2.4.2009, 14:03 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

Профиль
Группа: Участник
Сообщений: 59
Регистрация: 11.10.2008
Где: Україна

Репутация: 2
Всего: 2

А если так 

Код

#include <iostream>
using namespace std;

template<typename T> 
inline int arrlen(T *arr)
{
    return static_cast<int>(_msize(arr)/sizeof(T));
}

int main()
{
    int *arr = new int[100];

    cout<<arrlen(arr)<<endl;

    delete[] arr;

    return 0;
}

PM MAIL Skype   Вверх
Dmi3ev
Дата 2.4.2009, 14:15 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
***

Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 13
Всего: 41

Цитата
Т.к. если вы вдруг измените тип переменной size, то размер будет считаться неправильно. 

а зачем size другого типа, если я пишу:

Код

ar=new int[size]; 

 

хотя согласен, он может быть и беззнаковый и тд…
но size в данном случае не влияет на размер одного элемента, влияние оказывает new int, соответственно как раз так писать

Цитата
int size1=sizeof(size)*size;

ненадежно!
потому как, size — это количество элементов, и эта переменная будет неизменна, независимо от того какого типа будет массив и тд…

zim22, ты в этот раз не прав…

———————

PM MAIL   Вверх



















Страницы: (4) Все [1] 2 3 … Последняя »

Ответ в темуСоздание новой темы
Создание опроса
Правила форума «C/C++: Для новичков»
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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

  • FAQ раздела лежит здесь!

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 

0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »

Определение количества элементов и размера массива

Количество элементов массива задается при объявлении и не может быть изменено позже. Поэтому лучше количество элементов сохранить в константе или макросе и в дальнейшем указывать эту константу, например, при переборе элементов массива. Чтобы получить количество элементов массива динамически при выполнении программы, нужно общий размер массива в байтах разделить на размер типа. Получить эти размеры можно с помощью оператора sizeof . Пример динамического определения количества элементов массива:

Можно также воспользоваться макросом _countof() :

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

Объем памяти (в байтах), занимаемый массивом, определяется так:

Учебник C++ (Qt Creator и MinGW)
Учебник C++ (Qt Creator и MinGW) в формате PDF

Помощь сайту

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

длина динамического массива

знаю, что с помощью стандартных способов это невозможно (в c++), но, например, в Java это можно сделать с помощью метода length, а на c++ как это можно реализовать?

Следует учесть, что массивы могут быть и двумерными.

Заранее благодарен за любую помощь!

10 ответов

Спасибо, помогло :о)

НО. _msize возвращает значение только для памяти выделенной с помощью malloc(), а как быть с оператором new?

выводит 128. Коллеги, можно ли (поддерживается ли это системой) использовать new и _msize вместе?

Насколько я знаю, оператор new работает через malloc, который, в свою очередь через HeapAlloc. Аналогичная схема и с delete: delete -> free -> HeapFree.

Если эта схема правильная, то использование _msize — допустимо.

Господа, по-моему гораздо проще и элегантнее использовать схему аналогичную си-строкам — в конце массива хранить специальный элемент-терминатор (в простейшем случае 0), и узнавать размер, прогулявшись по массиву.

ЗЫ : А если код такой

1. Речь здесь идет совсем о другом.
2. strlen — функция, для работы со строками в стиле С (ASCII(Z)). Название темы внимательно прочитай. 🙂

Обсасываем проблему высосанную из пальца?
Если сам создал массив, значит должен и длину знать.
Если мучает склероз, сохрани длину в соотв. переменной, рядом с массивом.

Какие проблемы? В чем сложность? Зачем делать простые вещи через задние проходы?

Тут кстати, поблизости есть тема, о пользе контейнеров:)

мне нужно написать одну программку, но в ней массивы вида m[a][c]. причем a,b,c каждый раз разные, и подобных массивов очень много создается по ходу работы программы.

Вот я и решил что проще узнавать как-то размер блока памяти по указателю на него, чем хранить где-то количество элементов в таких массивах.

код для динамического массива путем ввода размера и сохранения его в переменную «n», но я хочу получить длину массива из метода шаблона, а не с помощью «n».

этот код похож, но с использованием динамический массив:

1 ответов

вы не можете. Размер массива, выделенного с помощью new[] не хранится каким-либо образом, в котором он может быть доступен. Обратите внимание, что возвращаемый тип new [] — это не массив — это указатель (указывающий на первый элемент массива). Так что если вам нужно знать длину динамического массива, вы должны хранить его отдельно.

конечно, правильный способ сделать это, избежав new[] и с помощью std::vector вместо этого, который хранит длину для вас, и это исключение-безопасно сапог.

Понравилась статья? Поделить с друзьями:
  • Как найти зарплатный проект в сбербанк
  • Как найти дату расторжения брака
  • Как найти документ содержащий фразу
  • Как составить план современного хозяйства
  • Как найти крутизну лестницы