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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.73
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
#1

Оператор delete[] - C++

13.07.2010, 12:58. Просмотров 1409. Ответов 13
Метки нет (Все метки)

Код:
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include  <iostream>
#include <cstdlib>
#include <ctime>
#define   stop __asm nop
 
int main()
{
        int N,M;
        N=3;
        M=4;
    
        //создаем указатель на одномерный динамический массив(1) с размерностями N*M
        int*pointer2dyn_arr=new int[N*M];
 
        //указатель на новый дин. массив(2), созданный для удобства обращения к элементам     одномерного массива
        int**pp2dyn_arr=new int *[N]; 
        
        //заполняем массив 2
        for(int i=0;i<N;i++)        
        {
            pp2dyn_arr[i]=pointer2dyn_arr+i*M;
        }
        
        //устанавливаем стартовую точку последовательности, которую генерирует rand()
        srand((unsigned)time(0));
        //заполняем массив 1
        for (int i=0;i<(N*M);i++)
        {
            pp2dyn_arr[0][i]=rand()%89+10;  //от 10 до 99
            if (i%M==0)std::cout<<'\n';
            std::cout<<pp2dyn_arr[0][i]<<' ';
            
        }
 
////  сумма элементов.
        int sum1=0; 
        for(int i= 0; i < (N*M) ; ++i)  
        {
            sum1+=pp2dyn_arr[0][i];
        }
        std::cout<<'\n';
    
    //Задание2а. В сформированном массиве отсортируйте каждую строку по
    //убыванию значений. Используйте сортировку "выбором"
 
        for(int k=0;k<N;++k) //пробегаем по строкам
        {
            for(int i = 0; i < (M) ; i++) //сортируем 
            {   
                int*max_el=pointer2dyn_arr;
                int*next_el=pointer2dyn_arr+1;
                for(int j=i+1;j<M;j++)  //пробегаем по ячейкам
                {
                    if(*next_el>*max_el)max_el=next_el;
                    next_el++;
                }
                int tmp=*max_el;
                *max_el=*pointer2dyn_arr;
                *pointer2dyn_arr=tmp;
                pointer2dyn_arr++;  
            }
        }
        
    //вывод отсортированных значений
        for (int i=0;i<(N*M);i++)
            {
                if (i%M==0)std::cout<<'\n';
                std::cout<<pp2dyn_arr[0][i]<<' ';
            }
        stop
    
        delete[] pointer2dyn_arr;
        pointer2dyn_arr=0;
        //delete[] pp2dyn_arr;
        //pp2dyn_arr=0;
        
        stop
return 0;
}
Во время выполнения выдает ошибку на 72 строке:
Debug Assertion Failed!
...
Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
...
вот что пишет в окне отладка:
Пр1сем.exe привело в действие точку остановка
HEAP[Пр1сем.exe]: Invalid address specified to RtlValidateHeap( 00520000, 005249A0 )
ОС Windows инициировала точку останова в Пр1сем.exe.

Это может быть вызвано повреждением кучи и указывает на ошибку в Пр1сем.exe или в одной из загруженных им DLL.

Возможной причиной так же может быть нажатие пользователем клавиши F12, когда фокус принадлежит Пр1сем.exe
Помогите, пожалуйста, разобраться с ошибкой.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.07.2010, 12:58
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Оператор delete[] (C++):

оператор delete[] - C++
Применение delete (без ) к указателю на массив освобождает только нулевой элемент, а оставшиеся создают утечку памяти, но как объяснить...

Оператор delete - C++
Вчера заметил, но ответа в сети так и не нашел: int *i = new int(5); cout &lt;&lt; *i &lt;&lt; endl; delete i; int p = *i; cout &lt;&lt; p &lt;&lt; ...

оператор delete - C++
#include &lt;iostream&gt; #include &lt;clocale&gt; #include &lt;iomanip&gt; using namespace std; int main() { setlocale (LC_ALL,&quot;russian&quot;); ...

Оператор delete[] - C++
Салют! тут вот в чем вопрос... Если с помощью new выделена память под несколько, скажем, массивов, то с помощью оператор delete удалять...

Оператор delete - C++
Написал небольшую программу и в просмотрел каждую строчку в отладчике. И получается что сразу же после оператора delete p_val; значение в...

Оператор delete в деструкторе - C++
Здравствуйте, нужна помощь, есть класс и функция к которую передается этот класс: #include&lt;iostream&gt; using namespace std; class...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
ForEveR
В астрале
Эксперт С++
7972 / 4734 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
13.07.2010, 14:09 #2
Ну вот так конечно работает... Но не полностью чистит память...

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include  <iostream>
#include <cstdlib>
#include <ctime>
#define   stop __asm nop
 
int main()
{
                int N,M;
                N=3;
                M=4;
        
                //создаем указатель на одномерный динамический массив(1) с размерностями N*M
                int*pointer2dyn_arr=new int[N*M];
 
                //указатель на новый дин. массив(2), созданный для удобства обращения к элементам     одномерного массива
                int**pp2dyn_arr=new int *[N]; 
                
                //заполняем массив 2
                /*for(int i=0;i<N;i++)
                    pp2dyn_arr[i]=new int[N];*/
                for(int i=0;i<N;i++)            
                {
                        pp2dyn_arr[i]=pointer2dyn_arr+i*M;
                }
                
                //устанавливаем стартовую точку последовательности, которую генерирует rand()
                srand((unsigned)time(0));
                //заполняем массив 1
                for (int i=0;i<(N*M);i++)
                {
                        pp2dyn_arr[0][i]=rand()%89+10;  //от 10 до 99
                        if (i%M==0)std::cout<<'\n';
                        std::cout<<pp2dyn_arr[0][i]<<' ';
                        
                }
 
////  сумма элементов.
                int sum1=0; 
                for(int i= 0; i < (N*M) ; ++i)  
                {
                        sum1+=pp2dyn_arr[0][i];
                }
                std::cout<<'\n';
        
        //Задание2а. В сформированном массиве отсортируйте каждую строку по
        //убыванию значений. Используйте сортировку "выбором"
 
                for(int k=0;k<N;++k) //пробегаем по строкам
                {
                        for(int i = 0; i < (M) ; i++) //сортируем 
                        {       
                                int*max_el=pointer2dyn_arr;
                                int*next_el=pointer2dyn_arr+1;
                                for(int j=i+1;j<M;j++)  //пробегаем по ячейкам
                                {
                                        if(*next_el>*max_el)max_el=next_el;
                                        next_el++;
                                }
                                int tmp=*max_el;
                                *max_el=*pointer2dyn_arr;
                                *pointer2dyn_arr=tmp;
                                pointer2dyn_arr++;      
                        }
                }
                
        //вывод отсортированных значений
                for (int i=0;i<(N*M);i++)
                        {
                                if (i%M==0)std::cout<<'\n';
                                std::cout<<pp2dyn_arr[0][i]<<' ';
                        }
                stop
                delete[] pp2dyn_arr;
                //pointer2dyn_arr=0;
                //delete[] pp2dyn_arr;
                //pp2dyn_arr=0;
                
                stop
return 0;
}
0
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
13.07.2010, 22:36  [ТС] #3
Цитата Сообщение от Lavroff Посмотреть сообщение
Ну вот так конечно работает... Но не полностью чистит память...
Если в моем примере удалить 72 строку(на которой появляется ошибка), то тоже все работает,
но не полностью чистит память...

Ошибка то в чем???
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
13.07.2010, 22:54 #4
Просто любопытства ради - что случается, если сначала удалять pp2dyn_arr?
0
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
13.07.2010, 23:03  [ТС] #5
Цитата Сообщение от Nick Alte Посмотреть сообщение
Просто любопытства ради - что случается, если сначала удалять pp2dyn_arr?
То же самое.
Ошибку выдает на этой же строке
C++
1
delete[] pointer2dyn_arr;
0
Bazan
22 / 22 / 0
Регистрация: 15.04.2009
Сообщений: 100
13.07.2010, 23:05 #6
Цитата Сообщение от st_dent Посмотреть сообщение
Если в моем примере удалить 72 строку(на которой появляется ошибка), то тоже все работает,
Ошибка то в чем???
В том, что в строке №60 операцией ++ ты не добавляешь 1 к значению pointer2dyn_arr, а изменяешь адрес, поскольку эта переменная инициализирована как указатель. Эта строчка должна выглядеть так:
*pointer2dyn_arr+=1;
еще попробуй
*pointer2dyn_arr++;
но этот вариант у меня не работает в отличие от первого.
1
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
13.07.2010, 23:15  [ТС] #7
Цитата Сообщение от Bazan Посмотреть сообщение
В том, что в строке №60 операцией ++ ты не добавляешь 1 к значению pointer2dyn_arr, а изменяешь адрес, поскольку эта переменная инициализирована как указатель.
Там и не надо изменять значение. Там указатель перемещается на следующий элемент массива.
0
Crudelis
Шаровик затейник
674 / 416 / 13
Регистрация: 06.05.2010
Сообщений: 1,109
13.07.2010, 23:29 #8
pointer2dyn_arr=0; после удаления самого pointer2dyn_arr зачем? если его после удаления нет
0
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
13.07.2010, 23:46  [ТС] #9
Bazan, Спасибо. Натолкнул на мысль.В данном случае, следует вернуть указатель на место(т.е. на начало массива).
добавить pointer2dyn_arr-=(N*M); на 63 строку
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include  <iostream>
#include <cstdlib>
#include <ctime>
#define   stop __asm nop
 
int main()
{
                int N,M;
                N=3;
                M=4;
        
                //создаем указатель на одномерный динамический массив(1) с размерностями N*M
                int*pointer2dyn_arr=new int[N*M];
 
                //указатель на новый дин. массив(2), созданный для удобства обращения к элементам     одномерного массива
                int**pp2dyn_arr=new int *[N]; 
                
                //заполняем массив 2
                for(int i=0;i<N;i++)            
                {
                        pp2dyn_arr[i]=pointer2dyn_arr+i*M;
                }
                
                //устанавливаем стартовую точку последовательности, которую генерирует rand()
                srand((unsigned)time(0));
                //заполняем массив 1
                for (int i=0;i<(N*M);i++)
                {
                        pp2dyn_arr[0][i]=rand()%89+10;  //от 10 до 99
                        if (i%M==0)std::cout<<'\n';
                        std::cout<<pp2dyn_arr[0][i]<<' ';
                        
                }
 
////  сумма элементов.
                int sum1=0; 
                for(int i= 0; i < (N*M) ; ++i)  
                {
                        sum1+=pp2dyn_arr[0][i];
                }
                std::cout<<'\n';
        
        //Задание2а. В сформированном массиве отсортируйте каждую строку по
        //убыванию значений. Используйте сортировку "выбором"
 
                for(int k=0;k<N;++k) //пробегаем по строкам
                {
                        for(int i = 0; i < (M) ; i++) //сортируем 
                        {       
                                int*max_el=pointer2dyn_arr;
                                int*next_el=pointer2dyn_arr+1;
                                for(int j=i+1;j<M;j++)  //пробегаем по ячейкам
                                {
                                        if(*next_el>*max_el)max_el=next_el;
                                        next_el++;
                                }
                                int tmp=*max_el;
                                *max_el=*pointer2dyn_arr;
                                *pointer2dyn_arr=tmp;
                                pointer2dyn_arr++;      
                        }
                }
                pointer2dyn_arr-=(N*M);
        //вывод отсортированных значений
                for (int i=0;i<(N*M);i++)
                        {
                                if (i%M==0)std::cout<<'\n';
                                std::cout<<pp2dyn_arr[0][i]<<' ';
                        }
                stop
        
                delete[] pointer2dyn_arr;
                pointer2dyn_arr=0;
                //delete[] pp2dyn_arr;
                //pp2dyn_arr=0;
                
                stop
return 0;
}


Как в данном случае можно проверить полностью ли освободилась память?

Добавлено через 11 минут
Цитата Сообщение от Crudelis Посмотреть сообщение
pointer2dyn_arr=0; после удаления самого pointer2dyn_arr зачем? если его после удаления нет
delete не удаляет указатель.Он освобождает блок памяти, адрес которого содержится в указателе. Т.к. значение адреса все еще хранится в указателе, безопаснее его обнулить.
0
easybudda
Модератор
Эксперт CЭксперт С++
9625 / 5573 / 947
Регистрация: 25.07.2009
Сообщений: 10,708
13.07.2010, 23:58 #10
Цитата Сообщение от st_dent Посмотреть сообщение
Там указатель перемещается на следующий элемент массива.
так в этом и проблема. после изменения значения указателя применять к нему операцию delete [] как-то не корректно. сделайте копию указателя и увеличивайте её значение. тогда указатель, для которого выделялась память оператором new [] будет пригоден и для оператора delete []
1
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
14.07.2010, 00:28  [ТС] #11
Цитата Сообщение от easybudda Посмотреть сообщение
так в этом и проблема. после изменения значения указателя применять к нему операцию delete [] как-то не корректно. сделайте копию указателя и увеличивайте её значение. тогда указатель, для которого выделялась память оператором new [] будет пригоден и для оператора delete []
вот так корректно будет память освобождена?
C++
1
2
3
4
5
6
7
8
//некий код
int*pointer2dyn_arr=new int[N*M];
pointer2dyn_arr++;
pointer2dyn_arr++;
pointer2dyn_arr=pointer2dyn_arr-2;
delete[] pointer2dyn_arr;
pointer2dyn_arr=0;
//ещё код
0
easybudda
Модератор
Эксперт CЭксперт С++
9625 / 5573 / 947
Регистрация: 25.07.2009
Сообщений: 10,708
14.07.2010, 00:33 #12
Цитата Сообщение от st_dent Посмотреть сообщение
вот так корректно будет память освобождена?
возможно, но я бы лучше не так делал...
C++
1
2
3
4
5
6
7
8
...
int*pointer2dyn_arr=new int[N*M];
int *pointer2dyn_arr_copy = pointer2dyn_arr;
pointer2dyn_arr_copy += 100500;
...
delete[] pointer2dyn_arr;
pointer2dyn_arr=0;
...
1
st_dent
64 / 64 / 3
Регистрация: 05.07.2010
Сообщений: 219
14.07.2010, 01:55  [ТС] #13
Цитата Сообщение от easybudda Посмотреть сообщение
возможно, но я бы лучше не так делал...
И всё-таки, почему бы вы так не делали?
Личный опыт? Поделитесь, пожалуйста.
Авторитетные источники? Поделитесь,пожалуйста.
0
easybudda
Модератор
Эксперт CЭксперт С++
9625 / 5573 / 947
Регистрация: 25.07.2009
Сообщений: 10,708
14.07.2010, 02:22 #14
Цитата Сообщение от st_dent Посмотреть сообщение
И всё-таки, почему бы вы так не делали?
Личный опыт? Поделитесь, пожалуйста.
Авторитетные источники? Поделитесь,пожалуйста.
Скорее личное мнение, основанное от части на опыте, от части на примерах из книг... Если указатель используется для выделения какого-то участка памяти, то лучше его значение не менять, пока в выделенной памяти нужда не отпадёт и она не будет освобождена. Так по крайней мере от подобных ошибок себя убережёте...
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.07.2010, 02:22
Привет! Вот еще темы с ответами:

Можно ли обобщить оператор delete ? - C++
Здравствуйте! Есть некоторый класс в котором есть указатель которому присваивается некоторое значение &quot;из-вне&quot; так сказать, так вот его...

Нужно ли тут вызывать оператор delete - C++
Всем здрасьте. Тут встал вопрос об операторе delete. struct x { //... }; x* y; y = new x; //...

Хочу понять когда можно делать оператор delete - C++
совсем новичок, а в книге толком не объясняется, помогите понять суть плиз Вот очень простой код: #include &lt;windows.h&gt; class...

Оператор delete(ошибка) - free(): invalid next size (fast): 0x098f7008 *** - C++
Делаю некое подобие функции itoa: char* c_itoa(int,char*,int):Реализацию сделал так(упрощённый вид):char* c_itoa(int number,char*...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
14.07.2010, 02:22
Ответ Создать тему
Опции темы

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