1 / 1 / 4
Регистрация: 23.08.2015
Сообщений: 458
1

Как предотвратить превышение размера массива?

12.02.2017, 13:26. Показов 2006. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Вот программа(из следующей темы функции new, delete)

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <conio.h>
#include <windows.h> // это для генерации случайных чисел(GetTickCount())
using namespace std;
 
class My_Class
{
private:
    int index;
    int * Array; // динамический массив.Мы не знаем его размер и содержание.
public:
    My_Class() : index(0) {}
    My_Class(int size) : index(0)
    {
        Array = new int [size]; // динамически выделяем память под массив
    }
    
    ~My_Class()
    {
        delete [] Array; // освобождаем память после использования,стираем массив.
    }
    void Fill_Array(int x)
    {
        Array[index] = x;
        index++;
    }
    int Show(int y)
    {
        return Array[y];
    }
};
 
int main()
{
    srand(GetTickCount());
    My_Class obj(20); // создаем массив из 20 элементов.
 
    int num;
    for(size_t i = 0; i < 20; i++)
    {
        num = rand() % 100;
        obj.Fill_Array(num); // заполняем массив случайными числами
    }
 
    for(size_t i = 0; i < 20; i++)
        cout <<obj.Show(i) << "  ";
 
 
_getch();
}
А вот теперь представим что в строках (39 и 45) мы добавим (=) после знака (<) или изменим (20 на 21) к примеру, и при всём при этом в строке (36) мы ведь задали уже размер массива, так почему-же программа запускается/работает показывая значения кол-во которых больше размера массива? поясните мне как это и почему.

Добавлено через 8 минут
Хочу понять почему так происходит, ведь по идее не должно такого быть! Покажите что как и где нужно изменить чтобы "превышения" не было. Заранее благодарен за помощь.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.02.2017, 13:26
Ответы с готовыми решениями:

Превышение размера стека
#include&lt;windows.h&gt; #include&lt;iostream&gt; using namespace std; //Дан квадратный массив. Розмер...

От класса String наследовать новый класс, который имеет проверку на превышение размера строки
Доброго времени суток! Решаю задачи из учебника Роберта Лафоре ООП в C++. До этой задачи все...

Ассемблерная вставка: превышение размера операнда
#include&lt;iostream&gt; #include&lt;stdio.h&gt; #include&lt;tchar.h&gt; using namespace std; int x; int...

Превышение размера файла cookie допустимое контейнером
Здравствуйте. Пытаюсь вытащить куки по определенному сайту, возникает ошибка на последней строке...

17
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
12.02.2017, 13:32 2
Цитата Сообщение от Maxim09 Посмотреть сообщение
так почему-же программа запускается/работает
Потому что компилятор не проверяет выход за границы массива. Но вы можете реализовать эту проверку в своём классе.
1
1 / 1 / 4
Регистрация: 23.08.2015
Сообщений: 458
12.02.2017, 13:36  [ТС] 3
Цитата Сообщение от likehood Посмотреть сообщение
Но вы можете реализовать эту проверку в своём классе.
Я попытался это сделать следующим способом:
C++
1
2
3
for(size_t i = 0; i < strlen(size); i++)
//или
for(size_t i = 0; i < strlen(Array); i++)
Но size и Array не видны для main функции попробовал sizeof тоже не то.
Подскажите, как можно реализовать проверку?
0
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
12.02.2017, 13:41 4
Цитата Сообщение от Maxim09 Посмотреть сообщение
так почему-же программа запускается/работает показывая значения кол-во которых больше размера массива?
Потому что по стандарту это UB, а в случае UB компилятор имеет право делать что угодно, вплоть до начала восстания машин.
Это вопрос из серии "почему я перебегал улицу на красный свет, а машина меня не сбила?". Бегайте дальше, рано или поздно собьет.
1
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
12.02.2017, 13:41 5
C++
1
for(size_t i = 0; i < obj.size(); i++)
Для этого нужно добавить в класс поле m_size и функцию size(), возвращающую значение этого поля.
1
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
12.02.2017, 13:44 6
Цитата Сообщение от Maxim09 Посмотреть сообщение
Я попытался это сделать следующим способом:
strlen работает только на строках (и показывает не размер массива, а позицию первого '\0'). Стандартного способа вытрясти размер массива созданного через new нет, его надо ручками где-то захомячить.
1
1 / 1 / 4
Регистрация: 23.08.2015
Сообщений: 458
12.02.2017, 13:48  [ТС] 7
likehood,

У меня вот что получилось но не до конца, как-то не получается дальше
C++
1
2
3
4
5
void size(size_t m_size)
    {
        m_size = 
    
    }
0
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
12.02.2017, 13:52 8
Лучший ответ Сообщение было отмечено Maxim09 как решение

Решение

Функция size должна возвращать значение m_size, а не устанавливать:
C++
1
size_t size() { return m_size; }
А устанавливать его нужно где-то в конструкторе.
1
1 / 1 / 4
Регистрация: 23.08.2015
Сообщений: 458
12.02.2017, 13:55  [ТС] 9
Цитата Сообщение от likehood Посмотреть сообщение
m_size
А где это можно установить? Я имею ввиду в private зоне? или непосредственно в конструкторе?

Это элемент класса так?
0
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
12.02.2017, 13:57 10
m_size - поле класса, в разделе private. Инициализируется в конструкторе.
1
1 / 1 / 4
Регистрация: 23.08.2015
Сообщений: 458
12.02.2017, 14:06  [ТС] 11
В итоге вышло следующее:
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>
#include <conio.h>
#include <windows.h> // это для генерации случайных чисел(GetTickCount())
using namespace std;
 
class My_Class
{
private:
    int m_size;
    int index;
    int * Array; // динамический массив.Мы не знаем его размер и содержание.
public:
    My_Class() : index(0) {}
    My_Class(int size) : index(0)
    {
        Array = new int [size]; // динамически выделяем память под массив
        m_size = size;
    }
    
    ~My_Class()
    {
        delete [] Array; // освобождаем память после использования,стираем массив.
    }
    void Fill_Array(int x)
    {
        Array[index] = x;
        index++;
    }
 
    size_t size() { return m_size; }
    int Show(int y)
    {
        return Array[y];
    }
};
 
int main()
{
    srand(GetTickCount());
    My_Class obj(20); // создаем массив из 20 элементов.
 
    int num;
    for(size_t i = 0; i < obj.size(); i++)
    {
        num = rand() % 100;
        obj.Fill_Array(num); // заполняем массив случайными числами
    }
 
    for(size_t i = 0; i < obj.size(); i++)
        cout <<obj.Show(i) << "  ";
 
 
_getch();
}
Благодарю всех за оказанную подмогу.

Добавлено через 5 минут
А как сделать m_size указателем?
0
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
12.02.2017, 14:09 12
Цитата Сообщение от Maxim09 Посмотреть сообщение
А как сделать m_size указателем?
Добавить звёздочку. Но зачем?
0
1 / 1 / 4
Регистрация: 23.08.2015
Сообщений: 458
12.02.2017, 14:11  [ТС] 13
Ну чтоб не занимало место в памяти а сразу указывало на элемент.
Я попробовал вот так (size_t а также int)* m_size но компилятор стал ругаться.
0
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
12.02.2017, 14:14 14
Цитата Сообщение от Maxim09 Посмотреть сообщение
Ну чтоб не занимало место в памяти
Экономия на спичках?
Указатель тоже занимает место в памяти, скорее всего столько же, сколько переменная типа size_t.
1
1 / 1 / 4
Регистрация: 23.08.2015
Сообщений: 458
12.02.2017, 14:15  [ТС] 15
Понятно спс.
0
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
12.02.2017, 14:19 16
Тем более вместо экономии будет дополнительный расход памяти: на сам объект, и на указатель. Указатели используются вовсе не для экономии памяти.
0
1 / 1 / 4
Регистрация: 23.08.2015
Сообщений: 458
12.02.2017, 14:25  [ТС] 17
Цитата Сообщение от likehood Посмотреть сообщение
Указатели используются вовсе не для экономии памяти.
А мне почему-то казалось что указатели используются если и не для экономии место то что-то близкое к этому кроме всех прочих свойств указателей
0
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
12.02.2017, 14:31 18
Возможно, имелось в виду, что указатели позволяют создать динамический массив, размер которого становится известным во время работы программы. В случае же использования статического массива мы вынуждены выделять память с запасом, в результате часть массива может оказаться неиспользуемой.
1
12.02.2017, 14:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.02.2017, 14:31
Помогаю со студенческими работами здесь

Превышение допустимого размера памяти в задаче (пилообразня последовательность)
&quot;Никогда такого не было, и вот опять!&quot; Не думал, что воззову о помощи на страницах форума, но...

Как предотвратить выход за границу массива в матрице
Дана матрица 10х10 int matrix={{1,2,3,4,5,6,7,8,9,0}, ...

StringGrid работа с TStrings и исключение "превышение размера StringGrid"
предположим есть TStringGrid и у него 10 строк и 2 колонки и есть TStringList и в нем 15 строк ...

Как отследить превышение по току?
Вопрос также звучит, как и название темы. Отслеживать необходимо с помощью МК. Есть какая-то...

Как обойти превышение длины пути?
Всем знатокам доброго времени суток! При переборе папок на диске возникает проблема - длина пути...

Дан целочисленный массив A размера N. Сформировать два новых целочисленных массива B и C одинакового размера, записав в
Привет,может кто сможет помочь с решением : Назовем серией группу подряд идущих одинаковых...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru