Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.89
petrovich1
0 / 0 / 0
Регистрация: 22.09.2007
Сообщений: 314
#1

Массив булевых элементов по входящему значению - C++

11.11.2011, 01:28. Просмотров 2508. Ответов 17
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
void mufunc(int range)
{
      bool M[???range???];
 
      for(int i = 0; i < range; i++)
           M[i] = false;
}
Надо объявить массив (динамический?) таким образом,
что-бы можно было задавать его размер по входящему в функцию значению.
По стандару нельзя объявлять размер массива (статического) значением, которое на момент компиляции не определено. Что делать? Голову сломал. Размер этого массива зависит именно от переменной range, делать его заведомо большим - некрасиво, к тому же есть ситуации, когда его все равно не хватит, то есть даже M[2000] - может не хватить в отдельных случаях. а иногда хватит и M[1].

Подскажите пожалуйста...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.11.2011, 01:28     Массив булевых элементов по входящему значению
Посмотрите здесь:

C++ Массив по значению
C++ передать массив в функцию по значению
Массив: Найти номера двух ближайших по значению элементов из этого массива и вывести их в порядке увеличения C++
C++ Одномерные массивы. Вывести на экран массив, составленный из номеров элементов исходного массива, которые равны заданному значению.
C++ Массив: Заменить последний из отрицательных элементов в массиве на три элемента, равных заданному значению.
C++ Сформировать массив С, каждый элемент которого равен максимальному значению соответствующих элементов массивов А и В
Сформировать массив С, каждый элемент которого равен максимальному значению соответствующих элементов массивов А и В C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
boombastik
7 / 7 / 0
Регистрация: 13.02.2007
Сообщений: 1,255
11.11.2011, 02:22     Массив булевых элементов по входящему значению #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
void mufunc(int range)
{
    bool* pM;
    
    pM = new bool[range];
    for(int i = 0; i < range; i++)
    {
        pM[i] = false;
    }
    
    delete[] pM;
}
Удачи, Владимир
petrovich1
0 / 0 / 0
Регистрация: 22.09.2007
Сообщений: 314
15.11.2011, 12:14  [ТС]     Массив булевых элементов по входящему значению #3
С-П-А-С-И-Б-О!
p.s. Что-то форум перестал на мыло автоматически скидываться
petrovich1
0 / 0 / 0
Регистрация: 22.09.2007
Сообщений: 314
16.11.2011, 23:34  [ТС]     Массив булевых элементов по входящему значению #4
Во-первых он вдруг (посде очередного ребилда) стал выдавать такое окно.
Во-вторых все-равно виснет. То есть память-то он выделяет, но при range > 10
на пятом вызове процесс падает! Я отслеживал через task manager, на каждом вызове (т.е. при каждом вызове ф-ии Сcurve) этот процесс памяти жрет все больше и больше. Почему??? Ведь delete же!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void Сcurve(int range)
{
    int q = 0;
 
    for(int i = 0; i < range; i++)
        q = (q * 2) + 1;
 
    bool* pM = new bool[q];
    int n = 0;
 
    for(int i = 0; i < range; i++)
    {   
        pM[n] = true;
        n = (n * 2) + 1;
        for(int j = (n/2)+1, k = (n/2)-1; j < n; j++, k--)  
            pM[j] = !pM[k];
    }
 
        // использование pM[]
 
    delete [] pM;
}
boombastik
7 / 7 / 0
Регистрация: 13.02.2007
Сообщений: 1,255
17.11.2011, 02:23     Массив булевых элементов по входящему значению #5
Хм... при range = 11 работает нормально выделяет массив bool переменных размером 2047, удаление тоже проходит на ура, при выходе в Debug режиме не пишет никаких ошибок. VC++ входящий в состав VS.NET 2002/2003/2005 при выходе из Debug режима автоматически отлавливает все memory leaks и выдает отчет о всех в Output окне.

Приведенный кусок программы работает без утечек памяти. Так что, либо ошибка/утечки в неприведенном куске кода (// использование pM[]), либо проблемы с компилятором/опциями компилятора.

С уважением,
Владимир

P.S. Использую VS.NET 2003 и VS.NET 2005 Beta 2 с указанной вами проблемой еще пока ни разу не сталкивался.
vagabond
0 / 0 / 0
Регистрация: 13.11.2011
Сообщений: 6
17.11.2011, 10:18     Массив булевых элементов по входящему значению #6
Привет.
Попробуй использовать std::vector<bool>:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <vector>
void Ccurve(int range)
{
       int q = 0;
 
       for(int i = 0; i < range; i++)
              q = (q * 2) + 1;
 
       //bool* pM = new bool[q];
       std::vector<bool> pM(range);
 
       int n = 0;
 
       for(int i = 0; i < range; i++)
       {
              pM[n] = true;
              n = (n * 2) + 1;
              for(int j = (n/2)+1, k = (n/2)-1; j < n; j++, k--)
                     pM[j] = !pM[k];
       }
 
// использование pM[]
 
       //delete [] pM;
}
Удачи.
petrovich1
0 / 0 / 0
Регистрация: 22.09.2007
Сообщений: 314
17.11.2011, 12:03  [ТС]     Массив булевых элементов по входящему значению #7
Цитата Сообщение от boombastik
Хм... при range = 11 работает нормально выделяет массив bool переменных размером 2047, удаление тоже проходит на ура, при выходе в Debug режиме не пишет никаких ошибок. VC++ входящий в состав VS.NET 2002/2003/2005 при выходе из Debug режима автоматически отлавливает все memory leaks и выдает отчет о всех в Output окне
при первом вызове Ccurve все хорошо. Но если например она вызывается при каждом клике правой кнопкой мышки в методе OnLButtonDown раз 5-6 подряд (даже с небольшими перерывами в 10 секунд) то падает!
petrovich1
0 / 0 / 0
Регистрация: 22.09.2007
Сообщений: 314
17.11.2011, 12:07  [ТС]     Массив булевых элементов по входящему значению #8
то M.S.N.
Спасибо, надо попробовать
Kovalsky2
0 / 0 / 0
Регистрация: 05.08.2009
Сообщений: 96
17.11.2011, 14:01     Массив булевых элементов по входящему значению #9
Цитата Сообщение от petrovich1
при первом вызове Ccurve все хорошо. Но если например она вызывается при каждом клике правой кнопкой мышки в методе OnLButtonDown раз 5-6 подряд (даже с небольшими перерывами в 10 секунд) то падает!
Увеличиваеться ли range при каждом вызове Ccurve?
К примеру если range==30,то это уже приблезительно 1 Гиг мозгов которые хотим
зарезервировать,и комп естественно засопративляеться.

функция void Сcurve(int range) правильная,тоько можно
добавить перед bool* pM = new bool[q]; проверку q на мега большое число,
и после bool* pM = new bool[q]; проверку pM на не равенcтво NULL.
petrovich1
0 / 0 / 0
Регистрация: 22.09.2007
Сообщений: 314
17.11.2011, 14:26  [ТС]     Массив булевых элементов по входящему значению #10
Цитата Сообщение от Kovalsky2
Увеличиваеться ли range при каждом вызове Ccurve?
К примеру если range==30,то это уже приблезительно 1 Гиг мозгов которые хотим
зарезервировать,и комп естественно засопративляеться.
в том-то и дело что нет! Не увеличивается. Оно одинаковое при каждом вызове.
Статистика памяти примерно такая:
при первом вызове: процесс ест 35% памяти
при втором: 65%
при третьем: 85%
при четвертом: 99%
при пятом вызове функции процесс падает
Kovalsky2
0 / 0 / 0
Регистрация: 05.08.2009
Сообщений: 96
17.11.2011, 15:23     Массив булевых элементов по входящему значению #11
На чём конкретно вылетает после 5 вызова?
petrovich1
0 / 0 / 0
Регистрация: 22.09.2007
Сообщений: 314
17.11.2011, 15:39  [ТС]     Массив булевых элементов по входящему значению #12
Сорри, под памятью я имел ввиду процессорное время (ну эти проценты в task manager). Я запускал в режиме without debuging, на пятом вызове приложение выдает окно "программа выполнила недопустимую операцию...", стандартное окно в XP. Как посмотреть конкретно на чем вылетает не знаю.
petrovich1
0 / 0 / 0
Регистрация: 22.09.2007
Сообщений: 314
17.11.2011, 15:41  [ТС]     Массив булевых элементов по входящему значению #13
а может экономичнее использовать массив int? Я все равно его как массив семафоров использую.
Kovalsky2
0 / 0 / 0
Регистрация: 05.08.2009
Сообщений: 96
17.11.2011, 15:49     Массив булевых элементов по входящему значению #14
2petrovich1
Поставте пару Breakpoints и пошагово пройдитесь по функции,и прикинте где вылетает.

А параллельные потоки в проге используете?
inserter
0 / 0 / 0
Регистрация: 13.08.2011
Сообщений: 5
17.11.2011, 16:08     Массив булевых элементов по входящему значению #15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void mufunc(int range)
{
      bool M[???range???];
 
      for(int i = 0; i < range; i++)
           M[i] = false;
}
 
Я бы сделал так:
void mufunc(int range) {
   bool *M;
   M = malloc(range*sizeof(bool));
   memset(M, 0, range*sizeof(bool));
}
Не забыть только потом free(M) сделать...
Но это если использовать C, идеология C++ может отличаться (не силен в этом вопросе).
petrovich1
0 / 0 / 0
Регистрация: 22.09.2007
Сообщений: 314
17.11.2011, 18:46  [ТС]     Массив булевых элементов по входящему значению #16
Все, нашел багу. Оказалось действительно в использовании pM. Утечка памяти была, но в другом месте. Но все равно полезный топик получился - три разных способа.
boombastik
7 / 7 / 0
Регистрация: 13.02.2007
Сообщений: 1,255
18.11.2011, 04:02     Массив булевых элементов по входящему значению #17
Да не, получается один C-шный способ ("устаревший"), один неэкономичный и один прямой ("в лоб").

Если программируешь на C++, то пользоваться C-шным способом не имеет смысла, предложенный первый способ с new/delete делает то же самое, только запись команд чуть более лаконична. Хотя странно, по-моему, в C нет типа bool, только если использвать #typedef bool int. malloc делает то же самое что и new, free эквивалетен delete, только вот в C-варианте придется вычислять размер памяти выделяемой под массив и при ее освобождении, а С++ операторы new и delete[] делают это автоматически (причем, насколько мне известно, на этапе компилирования).

Способ с вектором хоть и выглядит симпатичным (освобождение памяти происходит автоматически в деструкторе шаблона вектора), но очень прожорлив и в данном случае не имеет смысла. НО, если предполагается динамическое расширение массива, то я бы рекомендовал именно использование вектора, в противном случае его использование - бессмысленная потеря времени на ряд операций. Впрочем, STL неплохо оптимизирована, вполне возможно после компиляции с оптимизацией получиться близкий по производительности код к классическим С++ и С решениям.

С уважением,
Владимир
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.11.2011, 11:55     Массив булевых элементов по входящему значению
Еще ссылки по теме:

Даны двСформировать массив С, каждый элемент которого равен максимальному значению соответствующих элементов массивов А и В C++
C++ Найти количество элементов массива, каждый из которых меньше по значению, чем среднее среди элементов
C++ Найти количество элементов массива, каждый из которых меньше по значению чем среднее среди элементов
Ввести одномерный массив E(10), найти сумму элементов массива, индекс которых равен их значению C++
Сформировать массив B из максимальных по значению элементов каждой строки исходной матрицы A(MxN) C++

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

Или воспользуйтесь поиском по форуму:
petrovich1
0 / 0 / 0
Регистрация: 22.09.2007
Сообщений: 314
19.11.2011, 11:55  [ТС]     Массив булевых элементов по входящему значению #18
Остановился на new-delete< хотя в конкретно моем примере разницы никакой не было. Все три способа освобождались с одинаковой скоростью, и во всех трех случаях процесс падал при range = 25; и даже не запускался при range > 25;(писал "Out of memory")
На машине стоит 512 метров мозгов
Yandex
Объявления
19.11.2011, 11:55     Массив булевых элементов по входящему значению
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru