Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
sibiryk
0 / 0 / 0
Регистрация: 12.10.2014
Сообщений: 9
1

Задача на работу с динамическим массивом. HEAP CORRUPTION DETECTED

15.01.2017, 16:08. Просмотров 229. Ответов 7
Метки нет (Все метки)

Не понимаю причину ошибки. Подскажите пожалуйста.
HEAP CORRUPTION DETECTED: after Normal block (#318) at 0x00FE03B0.
CRT detected that the application wrote to memory after end of heap buffer.
Кликните здесь для просмотра всего текста
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
// pmArray.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
 
#include <stdio.h>
#include <math.h>
#include <clocale>
#include <stdlib.h>
#include <time.h>
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "Russian");
    setlocale(LC_ALL, "rus");
 
//Инициализируем функцию для заполнения массива случайным набором чисел.    
    srand(time(NULL));
 
// Указывавем переменные для организации меню и подменю.
    int menu = 0;
    int menu1 = 0;
    int wasEntRM = 0;
    int wasEntEM = 0;
    int wasCalc = 0;
 
//Задаем массив и его размер    
    int size = 0;
    int *a = new int[size]();
 
    printf("Выберите пункт меню.\n");
 
    do 
    {
        printf("1. Ввести количество элементов массива.\n");
        printf("2. Ввести значение элементов массива.\n");
        printf("3. Обработать массив в соответствии с задачей.\n");
        printf("4. Вывести результат обработки на экран.\n");
        printf("5. Вывести количество четных и нечетных элементов массива.\n");
        printf("0. Выход.\n");
 
        scanf("%d", &menu);
 
// Реализуем меню
        switch (menu)
        {
        case 1:
            do 
                {
                printf("Введите размер массива: ");
                scanf("%d", &size);
                if (size == 0 || size < 0) 
                    {
                        printf("ОШИБКА!!! Размер массива не может быть равен нулю или быть отрицательным!\n");
                    }                       
                } while (size == 0 || size < 0);
                wasEntRM = 1;
                wasEntEM = 0;
                wasCalc = 0;
                break;
 
        case 2:
            if (1 == wasEntRM)
            {
            printf("1. Ввести значения элементов массива с клавиатуры.\n");
            printf("2. Заполнить элементы массива автоматически.\n");
            scanf("%d", &menu1);
 
//Реализуем подменю
            switch (menu1)
            {
            case 1:
                    for (int i = 0; i < size; i++)
                        {
                            printf("Введите элемент №%d: ", i + 1);
                            scanf("%d", &a[i]);
                        }
                break;
            
            case 2:
                for (int i = 0; i < size; i++)
                {
                    a[i] = rand() % 100;
                }
                break;
            }
                wasEntEM = 1;
            }
            else
            {
                printf("Сначала нужно ввести размер массива!\n");
                printf("Выберите пункт меню 1.\n");
            }
//Сообщаем пользователю о введенных значениях элемента массива
            printf("Введены следующие значения: \n");
            for (int i = 0; i < size; i = i + 1)
            {
                printf("%d", a[i]);
 
                if (i == size - 1)
                {
                    printf("\n");
                }
                else
                {
                    printf(", ");
                }
            }
            break;
 
        case 3:
            if (wasEntEM != 0)
            {
                for (int i = 2; i < size; i = i + 2) //NB!: Поменять "int i = 2" на "int i = 0" если а[0] нужно считать за четный элемент массива
                {
                    if (a[i] < 0)
                    {
                        a[i] = a[i] - (a[i] * 2);
                    }
                    else if (a[i] > 0)
                    {
                        a[i] = a[i] + (a[i] * (-2));
                    }
                    else
                    {
                        a[i] = a[i];
                    }
                }
                printf("Массив обработан успешно.\n");
                wasCalc = 1;
            } 
            else
            {
                printf("Сначала нужно ввести элементы массива!\n");
                printf("Выберите пункт меню 2.\n");
            }
            break;
        case 4:
//Вывод результата изменения знака элемента массива
            if (wasCalc != 0)
            {
            printf("Результат: \n");
                        for (int i = 0; i < size; i = i + 1)
                        {
                            printf("%d", a[i]);
 
                            if (i == size - 1)
                            {
                                printf("\n");
                            }
                            else
                            {
                                printf(", ");
                            }
                        }
            }
            else
            {
                printf("Сначала нужно обработать массив!\n");
                printf("Выберите пункт меню 3.\n");
            }
            break;
        case 5:
            if (wasCalc != 0)
            {
// Задаем переменные для подсчета положительных и отрицательных элементов массива
            int aPlus  = 0;
            int aMinus = 0;
 
                for (int i = 0; i < size; i = i + 1)
                {
                    if (a[i] > 0)
                    {
                        aPlus = aPlus + 1;
                    }
                    else if (a[i] < 0)
                    {
                        aMinus = aMinus + 1;
                    }
                }
                    printf("Количество положительных элементов массива равно: %d\n", aPlus);
                    printf("Количество отрицательных элементов массива равно: %d\n", aMinus);
            }
            else
            {
                printf("Сначала нужно обработать массив!\n");
                printf("Выберите пункт меню 3.\n");
            }
            break;
        case 0:
            break;
        default:
            printf("Неверный пункт меню!\n");
        }
   
    } while (menu != 0);
    
    delete [] a; 
 
    getchar();
    getchar();
    return 0;
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.01.2017, 16:08
Ответы с готовыми решениями:

Heap corruption detected
В процессе разработки получилась интересная ситуация. Есть такой код char **map; map =...

HEAP CORRUPTION DETECTED
На строчке 36 с очисткой памяти постоянно вылетает ошибка дебага :( HEAP CORRUPTION DETECTED...

Что может означать такая ошибка: "Heap corruption detected"
Что может означать такая ошибка? переполнение памяти?

Задача "читателя и писателя" с буферным пулом (динамическим массивом)
Сама задача: Рассмотрим взаимодействие двух потоков, один из которых пишет данные в буферный пул,...

Heap corruption detected
Heap corruption на строке 93 при первом же выполнении цикла. Из-за чего? #include &lt;locale.h&gt; //...

7
likehood
984 / 828 / 396
Регистрация: 25.12.2016
Сообщений: 2,727
Завершенные тесты: 3
15.01.2017, 16:22 2
Для начала, программа написана на С++, а не Си.
Кроме того, хотелось бы узнать, при каких условиях возникает эта ошибка, потому что у меня всё работает нормально. Размер массива задал равным 10, заполнение автоматическое.
0
sibiryk
0 / 0 / 0
Регистрация: 12.10.2014
Сообщений: 9
15.01.2017, 16:34  [ТС] 3
likehood,
Для начала, программа написана на С++, а не Си.
Откуда это видно? В С++ насколько мне известно другие операторы. Это моя вторая программа в жизни на Си, много чего не знаю.
Кроме того, хотелось бы узнать, при каких условиях возникает эта ошибка, потому что у меня всё работает нормально. Размер массива задал равным 10, заполнение автоматическое.
У меня без ошибок отрабатывает если я сразу 0 выбираю. Если пробегаюсь по всем пунктам меню, независимо от размера массива, при выходе из программы выскакивает ошибка => запускается дебаггер. Я работаю в IDE MVS Community 2015. Возможно у нас разные версии компиляторов.
0
retmas
Жарю без масла
865 / 747 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
15.01.2017, 16:42 4
Цитата Сообщение от sibiryk Посмотреть сообщение
Откуда это видно?
это С++:
C++
1
2
3
#include <clocale>
,,,
int *a = new int[size];
Цитата Сообщение от sibiryk Посмотреть сообщение
другие операторы
это какие?
а на счет ошибки, посмотрите на эти строки внимательнее и поймете(я думаю)
C++
1
2
    int size = 0;
    int *a = new int[size]();
0
sibiryk
0 / 0 / 0
Регистрация: 12.10.2014
Сообщений: 9
15.01.2017, 16:59  [ТС] 5
retmas, нас усиленно учат Cи, примеры показывают на Си. Половина кода из примеров на Си состоит. По крайней мере нам так говорят.

Сообщение от sibiryk
другие операторы
это какие?
cout << или cin >> - например.

int size = 0; // Мысли в слух: Задали переменную для определения размера массива, но размер массива не может быть равен 0. Далее в коде мы это меняем. Если не обнулить переменную программа сразу после запуска выкидывает ошибку.
int *a = new int[size]();// Задали динамический массив размером size и обнулили значение элементов массива.

Деббагер сообщает:

Кликните здесь для просмотра всего текста

//
// delete_scalar.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Defines the scalar operator delete.
//
#include <crtdbg.h>
#include <malloc.h>
#include <vcruntime_new.h>



void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK);
#else
free(block);
#endif
}

0
likehood
984 / 828 / 396
Регистрация: 25.12.2016
Сообщений: 2,727
Завершенные тесты: 3
15.01.2017, 17:05 6
Цитата Сообщение от sibiryk Посмотреть сообщение
Далее в коде мы это меняем.
Меняется только переменная size. А нужно и массив создавать, после того, как пользователь введёт его длину.
P.S. Оператор new - это не Си, а С++.
0
retmas
Жарю без масла
865 / 747 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
15.01.2017, 17:20 7
Цитата Сообщение от sibiryk Посмотреть сообщение
nt size = 0; // Мысли в слух: Задали переменную для определения размера массива, но размер массива не может быть равен 0...
int *a = new int[size]();// Задали динамический массив размером size
сами же себе противоречите. подумайте получше.

Добавлено через 1 минуту
и отсутствие в коде cin / cout не означает, что код стал С а не С++. выше вам указали на признаки С++. и жрать ваш код будет только С++ компиль, но не С

Добавлено через 8 минут
хочется Си и создания дин. массива с нулевыми элементами? можно написать и так:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    int size = 0;
    int *a = NULL;
...
    do
    {
...
        // Реализуем меню
        switch(menu)
        {
        case 1:
...
            wasCalc = 0;
            a = calloc(size, sizeof(int));
            break;
...
    free(a);
0
MrGluck
Модератор
Эксперт CЭксперт С++
8108 / 4960 / 1436
Регистрация: 29.11.2010
Сообщений: 13,456
17.01.2017, 15:40 8
sibiryk, попробуйте сохранить исходник с расширением .c и вам VS сразу скажет в чём вы ошибались. При беглом взгляде, вам стоит только поменять операторы для работы с динамической памятью на спец. функции из Си. И сместить объявление всех переменных (в том числе параметров в циклах, ведь VS не умеет С99) в начало функции.

Добавлено через 56 секунд
И
C++
1
#include <clocale>
поменяйте на
C
1
#include <locale.h>
1
17.01.2017, 15:40
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.01.2017, 15:40

Heap corruption detected
При попытке очистить память выдает &quot;Heap corruption detected&quot;. Помогите пожалуйста( //...

HEAP CORRUPTION DETECTED
Собственно такую ошибку выдаёт: &quot;HEAP CORRUPTION DETECTED: after Normal block (#220) at 0x001970B8....

heap corruption detected
имеется класс CStr - строка, в нём есть конструктор CStr CStr::CStr(char *s) { length = 0;...


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

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

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