Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.52/64: Рейтинг темы: голосов - 64, средняя оценка - 4.52
8 / 8 / 5
Регистрация: 28.10.2012
Сообщений: 135

Можно ли обойти динамический массив не зная его размер?

11.04.2016, 02:13. Показов 13776. Ответов 79
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Массив ниже. 
Есть ли способ обойти такой массив используя указатель pArr на него? Не используя count.
 
    int count = 7;
    
    int *pArr = new int[count];
    
    int id = 0;
    while (id < count)
    {
        int value;
        cout << "pArr[" << id << "]=";
        cin >> value;
        pArr[id] = value;
        id++;
    }
    
    delete pArr;
        
    _getch();
    return 0;
1
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.04.2016, 02:13
Ответы с готовыми решениями:

Как создать двумерный динамический массив не зная его размеров?
Привет. Не смог найти в гугле как можно создать двумерный динамический массив не зная его длины вообще. Нашел только создание...

Можно ли создать массив, изначально не зная его размерности?
Доброго времени суток. Формируется некая последовательность (https://www.cyberforum.ru/pascalabc/thread1962554.html#post10342225) Нужно...

Можно ли задать массив, не зная заранее его длину?
Доброе утро всем. Вчера начал читать &quot;главу 4 Массивы&quot;. Там предложили 2 варианта объявления массива: 1) неинициализированный int...

79
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
11.04.2016, 22:05
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от nmcf Посмотреть сообщение
IGPIGP, почему тебя так размер волнует? Это главный признак правильного массива?
Признак типа "массив", это тип массив. Передайте ссылку на массив в функцию и она легко, без читерства определит размер. Это потому что тип поддерживает оператор sizeof. Указатель его тоже поддерживает, он же тип. Поэтому его размер - размер указателя. Неужели мы говорим на разных языках? Указатели можно использовать по разному. Можно десятичные в 16-ричные конвертировать. Показать?
Но это не значит, что указатель, - конвертер. Он об этом и не догадается.
1
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
11.04.2016, 22:14
Цитата Сообщение от IGPIGP Посмотреть сообщение
Признак типа "массив", это тип массив.
Вот это придумали теоретики, ограничив понятие массив только тем, что объявлено на момент компиляции, наверное, чтобы строго изложить описание языка. Только как тогда называть то, что по сути массив, но не массив с точки зрения теории? Квазимассив?
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
11.04.2016, 22:20
Цитата Сообщение от nmcf Посмотреть сообщение
Только как тогда называть то, что по сути массив, но не массив с точки зрения теории? Квазимассив?
Существует понятие типа. В этом контексте массивы C++ определены вполне точно. В информатике существует более общее понятие. Они похожи. Однако то что принято называть динамическим массивом это не тип данных С++. И когда это не разграничивают, постоянно задают вопросы которых не должно быть.
Любой тип с точки зрения низкоуровневого размещения это массив байт. Это если говорить о уровнях абстракции там, где не нужно бы.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
11.04.2016, 22:24
Цитата Сообщение от nofx Посмотреть сообщение
Есть ли способ обойти такой массив используя указатель pArr на него? Не используя count.
не портируемые. или ручные велосипеды.
никаких гарантий.
_msize выдает размер блока, который гарантированно не меньше,
но может быть больше, например.

Цитата Сообщение от nmcf Посмотреть сообщение
Т. е. массив не может быть в памяти, выделенной new?
стандарт однозначно определяет понятие термина.
"массив данных" не имеет к нему никакого отношения.
1
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
11.04.2016, 22:25
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
castaway, тоесть мой ответ не верный и мне не полагается балл?(
А ты только из-за баллов тут находишься? Твой ответ спорный, да и вообще вся тема спорная, холиварная...
По поводу баллов - я не тот кто их раздаёт. Мне на них плевать.
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
11.04.2016, 22:32
То, что это не тип данных, не позволяет говорить, что динамических массивов в C++ нет.
0
11.04.2016, 22:32

Не по теме:

castaway, это же была очевидная цитата с теле-программы.

0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
11.04.2016, 22:41
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
и куску кода:
template<typename T, std::size_t N> * * * * * * * *
std::size_t arraySize(T(&)[N])* * * * * * * * * * *
{
* * return N;
}
не имейте привычки писать туловище функций
которые предназначены для компалтайм вычислений.


http://rextester.com/BAWA95629

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
// макетами называют функции, 
// которые не нуждаются в туловищах
// для их работоспособности достаточно лишь прототипа
template<class T, size_t N>
char (&size( T (&arr)[N] ) )[N];
 
int main()
{
    std::cout << "Hello, world!\n";
    
    int a[10];
    
    // что бы вычислить размер переданного в аргументе массива
    // компилятору нет нужды запускать саму функцию
    // поэтому, она не нуждается в туловище
    enum { count = sizeof( size(a) ) };
 
    std::cout <<"count = " << count <<std::endl;
}
2
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
11.04.2016, 22:53
hoggy, и тем самым ваш код стал еще "не читабельнее".
C++
1
 enum { count = sizeof( size(a) ) };
Без всего кода, я бы сразу не понял, что этим хотел сказать программист.
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
11.04.2016, 22:58
Т. е. это просто способ получить размер в элементах, а не в байтах?
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
11.04.2016, 23:13
Цитата Сообщение от IGPIGP Посмотреть сообщение
Во-первых это читерство, а во вторых для таких типов как int нет терминатора
char это unsigned __int8. в 16-битных компиляторах char это unsigned short int. В чем разница? В количестве байт? Она не существенна, хотя бы потому что существует двубайтовый wchar_t. Четкого понятия терминатора для строки кстати тоже нет. Если 0 является терминатором используемым в функциях из набора strxxx это еще не значит что это единственный возможный терминатор. Те же прерывания ДОС в качестве терминатора используют '$'. А возможно использование '\r' и '\n'. а так же бывает пользуют ETX или ETB.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
12.04.2016, 00:18
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
char это unsigned __int8
char это char. То что в ряде реализаций размер типов совпадает не причина считать, что это одно и то же самое. Даже то, что char это целый тип и приводится к целому в выражении где ожидается целое, не значит, что char и short это одно и то же. Когда вычисляется:
C++
1
cout<<a;
то если a это char то будет печататься символ, а если это целое то напечатается число. Но терминатор имеет смысл не для char а для с-строк. А это указатели на char.
Fulcrum_013, поскольку мы не понимаем друг друга в таких простых вещах как char != int и (int*) !=[]int то в с-строки предлагаю не уходить. И так нагородили, - будь здоров.
ps если Вы знаете число которое можно использовать в качестве терминатора для, скажем, int то напишите его.
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
12.04.2016, 09:35
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
хотя бы потому что существует двубайтовый wchar_t
кто сказал, что оно два байта?
Одной виндой мир не ограничен. У меня, например, оно 4 байта.
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
char это unsigned __int8
Нет такого типа как __int8, если в Вашем компиляторе char реализован именно так,
то это не значит что так оно везде.
Да, он целочисленный, да, занимает один байт, но, например, кто сказал что он unsigned?
char может быть как беззнаковым, так и знаковым - это определяется реализацией.
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Нам по другому объясняли. Массив в C и C++ это указатель на его начало. Неважно где он выделен, но это именно указатель на его начало.
Имя массива приводится к указателю без проблем,
только вот имя массива несет в себе дополнительную метаинформацию,
которая теряется при decay типа до указателя.
Не понимание этого момента может сильно стукнуть по башке в шаблонах.
2
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9005 / 4706 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
12.04.2016, 10:21
Цитата Сообщение от Croessmah Посмотреть сообщение
может сильно стукнуть по башке
Без шаблонов тоже может.
Меня вот всегда занимал вопрос удивительного отличия delete от delete []. Утверждается, что оно в том, что первый запускает деструктор для объекта по указателю где память выделялась оператором new, а второй, - для всех объектов, под которые память которые выделена оператором new[]. То есть, похоже что не просто "каждый компилятор желает знать, где сидит фазан"! Похоже, что каждый компилятор знает размер или может его узнать. Пусть память выделяется и освобождается операционной системой, по запросу программы, но конструкторы и деструкторы же не передаются? Значит информация должна где-то быть у программы?
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
12.04.2016, 10:39
Цитата Сообщение от Croessmah Посмотреть сообщение
Не понимание этого момента может сильно стукнуть по башке в шаблонах
Я на это смотрю немного по другому. А именно для статического массива размер куска памяти на который он указывает определяем при компиляции.

Добавлено через 7 минут
Цитата Сообщение от IGPIGP Посмотреть сообщение
Похоже, что каждый компилятор знает размер или может его узнать.
Компилятор его не знает. Но его обязан знать менеджер кучи.
Цитата Сообщение от IGPIGP Посмотреть сообщение
Меня вот всегда занимал вопрос удивительного отличия delete от delete []
Как бы как бы. К примеру борландовский менеджер кучи в купе с кодегуардом позволяют пользовать delete для любых блоков и все ок. Начиная с версии Turbo C++ 1.0. Что говорит о том что менеджер кучи знает какого размера блок и соответсвенно сколько в нем элементов и т.д., и даже скорее всего знает какого они типа. Но при этом в документации написано что must use delete[] for arrays. А ноги растут оттуда что delete и delete[] перегружаемые операторы и не факт что все перегрузки окажутся настолько же умными как штатный менеджер кучи. Соответственно менеджер кучи хранит что-то в своих таблицах закрытым от общественности способом.
0
return (true);
 Аватар для mimicria
1977 / 1112 / 221
Регистрация: 19.04.2011
Сообщений: 2,346
12.04.2016, 10:55
Цитата Сообщение от IGPIGP Посмотреть сообщение
Утверждается, что оно в том, что
Не утверждается, а действительно так.
Попробуйте сами:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
 
class deltest
{
 int P;
 public:
 deltest(int a=0):P(a){cout<<"Constructor"<<endl;}
 ~deltest(){cout<<"Destructor"<<endl;}
};
 
int main(int argc, char* argv[])
{
 deltest *mas = new deltest[3];
 delete [] mas;
 return 0;
}
Если убрать [] вызовется один деструктор, а потом access violation
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
12.04.2016, 11:05
Цитата Сообщение от IGPIGP Посмотреть сообщение
Значит информация должна где-то быть у программы?
Как правило, new[] выделяет чуть больше памяти, чем нужно для хранения элементов.
Добавляется некий хвостик перед основным буфером, который содержит число элементов,
собственно при new такой хвостик может отсутствовать, дабы не нужен,
соответственно операции new/new[] delete/delete[] должны соответствовать друг другу.
Вот пример: Передача по ссылке двумерного динамического массива в функцию
1
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
12.04.2016, 11:16
Цитата Сообщение от mimicria Посмотреть сообщение
Если убрать [] вызовется один деструктор, а потом access violation
В MSVC. В BCC все будет ок, как будто вызвался []. Другие компиляторы в этом плане не тестировал. Но есть точная инфа что в первых компиляторах нужно было не просто delete[] а delete [Size]. Что говорит о том что все это зависит исключительно от умности менеджера кучи (набора информации который он пишет в свои таблицы при выделении блока)
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
12.04.2016, 11:24
Цитата Сообщение от mimicria Посмотреть сообщение
Если убрать [] вызовется один деструктор, а потом access violation
потому как реальный указатель, который нужно удалить может отличаться.
Например:

Как видим, работа new и new[] может отличаться.
И вообще может вернуться указатель не на выделенную память,
а на некий определенный участок этой памяти.

Вот, например, при использовании delete оно знает, что объект один,
вызывает деструктор и передает адрес дальше в функцию освобождения(operator delete).
А теперь смотрите что получается, если мы передадим сюда то, что вернул нам new[],
то получим вызов одного деструктора и передачу в operator delete указателя,
только вот этот указатель уже не на выделенную память,
а несколько другой(тот, который вернулся пользователю).
Соответственно получим черт пойми что.
А если бы использовали delete[], то вот он уже знает о наличии хвоста и отработает корректно.

И рассмотрим обратную ситуацию.
Память выделялась с помощью new, а удаляется с помощью delete[].
delete[] предполагает, что есть хвост, ломится туда, читает оттуда кол-во элементов
и вызывает деструкторы для данного кол-ва объектов.
А теперь вопрос: что у нас в этом хвосте, если память выделялась new и никакого хвоста нет?
Правильно! Неизвестно что там.
Может 0, а может 100500.
Соответственно уже имеем UB (не наша память + вызов деструкторов для несуществующих объектов).
Плюс к этому добавляется то, что в operator delete уйдет указатель, смещенный "назад" на размер хвоста,
что также приведет к неопределенным последствиям.
Вызвали бы delete вместо delete[], то всё бы было нормально.

По ссылке выше есть пример "перезаписи" этого "хвоста".
5
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
12.04.2016, 11:59
Цитата Сообщение от Croessmah Посмотреть сообщение
Как видим, работа new и new[] может отличаться.
И вообще может вернуться указатель не на выделенную память,
а на некий определенный участок этой памяти.
Это только один из многих возможных способов работы менеджера кучи. Опять же если выделяем память под один экземпляр пользовательского типа хвост никуда не денется, размер все равно нужон,либо не размер а пометка номера типа. То же самое в принципе касается и фундаментальных типов. Но для фундаментальных типов оверхед будет чуть ли не больше самих данных. Поэтому и работает менеджер кучи с ними по разному. простейший пример - битовая карта занят/свободен на каждый байт, что дает гарантированно оверхед не более 1/8. И такой менеджер кучи похоже и был у С++ в исходе, откуда и была необходимость указывать размер в delete[]. Но во первых при изменяемом размере кучи не самый удобный вариант, во вторых при выделении больших кусков способ с заголовком дает гораздо более меньший оверхед. Поэтому есть такое подозрение что современные менеджеры памяти пользуют сразу несколько сегментов кучи, в одном выделяют большие куски с заголовками, а для единичного распределения фундаментальных типов пользуют другой сегмент кучи с картой распределения.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
12.04.2016, 11:59
Помогаю со студенческими работами здесь

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

Создать динамический массив, размер которого пользователь вводит с клавиатуры.Заполнить его случайными числами
Кто знает, как на С++: создать динамический массив, размер которого пользователь вводит с клавиатуры. Заполнить его случайными числами из...

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

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

Рассчитать размер 1 пикселя в мм на мониторе,зная диагональ монитора в дюймах и его разрешения
Рассчитать размер 1 пикселя в мм на мониторе,зная диагональ монитора в дюймах и его разрешения


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru