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

Точка останова(повреждение кучи) - C++

Восстановить пароль Регистрация
 
Mukue
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 35
04.01.2014, 14:48     Точка останова(повреждение кучи) #1
Прошу помочь, смотрел по форуму похожие темы - ответа не нашел
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
void Base::Read()
{
    char* name=new char[];//переменная для имени
    char* str=new char[];//для построчного чтения файла
    ifstream in;//поток для чтения
    bool flag=true;
    do //открываем файл
    {
        cout<<"Please, enter file name: ";
        cin>>name;
        in.open(name, ios::binary);
        if (!in)
        {
            flag = false;
        }
    }while(!flag);
    int i=0;
    while(i<2)
    {
        i++;
        in.getline(str, 80);
    }
    
    delete [] name; //не удаляется
    delete [] str; //а здесь показывается сообщение
    in.close();
}
Добавлено через 14 минут
Вот, исправил:
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
void Base::Read()
{
    char* name=new char[];//переменная для имени
    char* str=new char[];//для построчного чтения файла
    ifstream in;//поток для чтения
    bool flag=true;
    do //открываем файл
    {
        cout<<"Please, enter file name: ";
        char arr2[80];
        cin>>arr2;
        in.open(arr2, ios::binary);
        if (!in)
        {
            flag = false;
        }
    }while(!flag);
    int i=0;
    while(i<6)
    {
        char arr[80];
        in.getline(arr, 79);
        i++;
        
    }
    
    //delete [] name;
    //delete [] str;
    in.close();
}
Но кто может объяснить, как сделать так, чтобы не создавать отдельно массивы и почему такое происходит?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.01.2014, 14:48     Точка останова(повреждение кучи)
Посмотрите здесь:

МНК, повреждение кучи C++
C++ Ошибка о повреждение кучи
C++ Повреждение кучи
Повреждение кучи C++
C++ Повреждение кучи
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.01.2014, 15:32     Точка останова(повреждение кучи) #2
Вот такое компилируется?
C++
1
char* name=new char[];
outoftime
║XLR8║
 Аватар для outoftime
505 / 427 / 33
Регистрация: 25.07.2009
Сообщений: 2,297
04.01.2014, 15:39     Точка останова(повреждение кучи) #3
Mukue, ИМХО код бредовый, что сделать пытаешься то?
coloc
погромист
 Аватар для coloc
409 / 245 / 15
Регистрация: 27.08.2012
Сообщений: 550
Завершенные тесты: 1
04.01.2014, 15:54     Точка останова(повреждение кучи) #4
Mukue, нормальный компилятор такое не скомпилирует. Ты выделяешь память под ноль символов? Где логика? Нужно так хотя бы
C++
1
char* name=new char[10];
Mukue
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 35
04.01.2014, 16:47  [ТС]     Точка останова(повреждение кучи) #5
на с++ программирую пол месяца от силы, перехожу с с #, мне нужно, чтобы считывалось имя файла, открывался поток для чтения файла с этим именем, потом каждую строку хочу закидывать в указатель, чтобы с ним уже в дальнейшем работать.

Добавлено через 6 минут
C++
1
char* name=new char[10];
мой скомпилил, логика в том, что я не знаю заранее сколько мне символов нужно на имя, поэтому и выделяю память на 0 символов в надежде на то, что когда я присвою другое значение, память увеличится)

Добавлено через 3 минуты
Больше всего бесит то, что границы массива нужно задавать заранее, поэтому надеюсь на указатели=(
а в указателях в лишней памяти какой-то мусор=(

Добавлено через 11 минут
Вот, вопрос, допустим я сдлал указатель char *arr2=new char[10]; Почему в таблице контрольных значений там уж точно не 10 символов?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.01.2014, 16:53     Точка останова(повреждение кучи) #6
Mukue, вы выкладывайте код, который, хотя бы, компилируется, а то так не разобраться.
Сначала у вас так (это не будет компилироваться):
C++
1
char* name=new char[];
Потом так:
C++
1
char* name=new char[10];
Какого размер str, когда ошибку выдаёт, так и не видно.

Добавлено через 59 секунд
Цитата Сообщение от Mukue Посмотреть сообщение
мой скомпилил, логика в том, что я не знаю заранее сколько мне символов нужно на имя, поэтому и выделяю память на 0 символов в надежде на то, что когда я присвою другое значение, память увеличится)
С чего это она увеличтся? Для таких дел string есть (автоматическое управление памятью).
Mukue
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 35
04.01.2014, 17:02  [ТС]     Точка останова(повреждение кучи) #7
C++
1
char* name=new char[];
у меня компилилось, vs 2010

у меня на указатель выделяется ровно 29 символов, потом записываются из другого массива символы через [i] с увеличением i, к концу когда доходит( при отладке) после нужной мне строчки еще куча мусора откуда то находится в значении, вы мне предлагаете на стринги перейти хД?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.01.2014, 17:19     Точка останова(повреждение кучи) #8
Проблема непонятна. Что, собственно, не работает? Почему код из первого поста ошибку выдавл уже понятно: памяти достаточно не выделялось. Если так написать, то ошибки уже не будет:
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
void Base::Read()
{
    char* name=new char[50];//переменная для имени
    char* str=new char[255];//для построчного чтения файла
    ifstream in;//поток для чтения
    bool flag=true;
    do //открываем файл
    {
        cout<<"Please, enter file name: ";
        cin>>name;
        in.open(name, ios::binary);
        if (!in)
        {
            flag = false;
        }
    }while(!flag);
    int i=0;
    while(i<2)
    {
        i++;
        in.getline(str, 255);
    }
    
    delete [] name; 
    delete [] str; 
    in.close();
}
Что ещё?
Mukue
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 35
04.01.2014, 17:57  [ТС]     Точка останова(повреждение кучи) #9
Допустим вот, метод для того, чтобы выделить из строки, заданной массивом char, выделить строку между пробелами на позиции left и right, может и тупой метод, но какой есть. Я спрашиваю только насчет случая, когда right = число, left = 0, у меня
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
char* Base::SplitCharArray(char arr[], int left, int right)
{
    int indexl, //индекс начала
        indexr; //индекс конца
    
    if(left!=0)
    {
        for(int i=0,j=0; i<strlen(arr);i++)
        {
            if (arr[i]==' ')
            {
                ++j;
                if (j==left)
                {
                    indexl=i+1;
                    break;
                }
                
            }
        }
        for (int i=indexl,j=left;i<strlen(arr);i++)
        {
            if (arr[i]==' ')
            {
                ++j;
                if (j==right)
                {
                    indexr=i;
                    break;
                }
                
            }
        }
        char *arr2=new char[indexr-indexl];
        for (int i=indexl; i<indexr;i++)
        {
            arr2[i]=arr[i];
        }
        return arr2;
    }
    else
    {
        for (int i=0,j=0;i<strlen(arr);i++)
        {
            char ch=arr[i];
            if (arr[i]==' ')
            {
                ++j;
                if (j==right)
                {
                    indexr=i;
                    break;
                }
                
            }
        }
        //char *arr2=new char[indexr];
        char arr2[80], *p;
        p=arr2;
        for (int i=0; i<indexr;i++)
        {
            p[i]=arr[i];
        }
        return p;
    }
}
Тут после выполнения у меня в arr2 помимо строчки откуда то появляется еще мусор, т.е. выделили память под 80 символов, заняли не все, а остальные под что попало.
Потом переходим в ту функцию read:
C++
1
2
3
4
5
6
7
8
9
10
11
12
while(in.getline(str, 79)!=NULL)
    {
        
        block=new char[20];
        strcpy(block,SplitCharArray(str, 0, 3));
        while(*block)
        {
            cout<<*block;
            block++;
        }
        delete []block;
    }
в блок у меня даже не записывается та строчка, которую я в методе получил, а только мусор( Я вот думаю, может мне на векторы или вообще на строки перейти.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.01.2014, 19:06     Точка останова(повреждение кучи) #10
Цитата Сообщение от Mukue Посмотреть сообщение
Тут после выполнения у меня в arr2 помимо строчки откуда то появляется еще мусор, т.е. выделили память под 80 символов, заняли не все, а остальные под что попало.
Мусор там и был, это не важно. Важно, чтобы Си-строка заканчивалась '\0'. Все функции, которые работают с такими строками, понимают этот символ как конец строки. Если строка создаётся вручную (не с помощью функций чтения, которые сами добавляют '\0' в конец считанной строки), то нужно и вручную добавлять '\0' в конец строки.

Добавлено через 4 минуты
Потом, вот это неправильно:
C++
1
2
3
4
5
6
7
char arr2[80], *p;
p=arr2;
for (int i=0; i<indexr;i++)
{
    p[i]=arr[i];
}
return p;
arr создается не в динамической памяти, а локально (на стеке), значит, после выхода из функции, его уже нет. Возвращать указатель (p) на локально созданный объект - ошибка.

Добавлено через 3 минуты
C++
1
while(in.getline(str, 79)!=NULL)
Сравнение с NULL тут лишнее. Можно просто:
C++
1
while(in.getline(str, 80))
И не нужно, в параметрах getline(), количество считанных символов уменьшать на 1, getline() сама это делает.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
04.01.2014, 19:44     Точка останова(повреждение кучи) #11
C++
1
char* name=new char[];
Студийный компилятор такое съедает. Если привести к Стандарту, то эквивалент такой:
C++
1
char* name=new char[0];
Конструкция разрешенная, но разыменовывать такой указатель, а тем более писать по этому адресу нельзя. Иначе UB.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.01.2014, 19:58     Точка останова(повреждение кучи) #12
Цитата Сообщение от Tulosba Посмотреть сообщение
Студийный компилятор такое съедает. Если привести к Стандарту, то эквивалент такой:
В студии съедает, но подчёркивает char и пишет (в подсказке): недопустимый неполный тип. Я поэтому и писал, что не компилируется (верил подсказке), а если запустить построение, то скомпилируется.
Цитата Сообщение от Tulosba Посмотреть сообщение
Конструкция разрешенная
mingw не компилирует.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
04.01.2014, 20:13     Точка останова(повреждение кучи) #13
Цитата Сообщение от alsav22 Посмотреть сообщение
mingw не компилирует.
C++
1
char* name=new char[0];
Этот?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
04.01.2014, 20:22     Точка останова(повреждение кучи) #14
Цитата Сообщение от Tulosba Посмотреть сообщение
Этот?
Нет. Понял: эта разрешённая.
Mukue
0 / 0 / 0
Регистрация: 08.02.2013
Сообщений: 35
04.01.2014, 23:39  [ТС]     Точка останова(повреждение кучи) #15
Я уже этот язык не люблю, подскажите пожалуйста, делаю все, как на примерах, но не работает(
vector<char>* student=new vector<char>[7];
student[0]=new vector<char>(SplitCharArray(str,0,3));
//student[1]=new vector<char>(SplitCharArray(str,3,4));
//student[2]=vector<char>(SplitCharArray(str,4,5));
//student[3]=new vector<char>(SplitCharArray(str,5,6));
//student[4]=new vector<char>(SplitCharArray(str,6,7));
//student[5]=new vector<char>(SplitCharArray(str,7,8));
//student[6]=new vector<char>(SplitCharArray(str,8,9));

Ведь я создал указатель размером 7, почему я не могу выделять память на новые вектора? пишет нет такого преобразования, если без new писать, то удается присвоить только 0 вектор=( Как сделать указатель на 7 векторов?

Добавлено через 36 минут
нашел, ошибка была в методе
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.01.2014, 03:10     Точка останова(повреждение кучи)
Еще ссылки по теме:

Ошибка при "сборе мусора" . Повреждение кучи C++
Повреждение кучи C++
C++ Повреждение кучи при создании нейросети с количеством слоев больше 51

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

Или воспользуйтесь поиском по форуму:
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.01.2014, 03:10     Точка останова(повреждение кучи) #16
new с векторами - это лишнее, вектор сам-по себе - new (создаётся в динамической памяти). И вектор автомитически управляет размером необходимой памяти, поэтому можно не задавать ему размер (при желании можно резервировать: reserv()):
C++
1
2
3
4
5
6
7
8
9
10
vector<char*> v; // вектор указателей
 
// добавляем в вектор указатели   
v.push_back(SplitCharArray(str,0,3));
v.push_back(SplitCharArray(str,3,4));
v.push_back(SplitCharArray(str,4,5));
v.push_back(SplitCharArray(str,5,6));
v.push_back(SplitCharArray(str,6,7));
v.push_back(SplitCharArray(str,7,8));
v.push_back(SplitCharArray(str,8,9));
Yandex
Объявления
05.01.2014, 03:10     Точка останова(повреждение кучи)
Ответ Создать тему
Опции темы

Текущее время: 12:46. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru