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

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

Войти
Регистрация
Восстановить пароль
 
bytephone32
1 / 1 / 0
Регистрация: 08.08.2012
Сообщений: 21
#1

Повреждение кучи - C++

17.10.2012, 04:30. Просмотров 1032. Ответов 4
Метки нет (Все метки)

Task2.h

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
#ifndef _TASK2_H_
#define _TASK2_H_
 
#include <iostream>
 
using namespace std;
 
namespace TeamResult
{
    static int fieldCnt = 1;
 
    static double planPctMax;
    static double planPctMin;
    
    typedef struct TR
    {
        char day[32];
        double plan;
        double realDo;
    } FIELD;
 
    typedef TR* DATABASE;
 
    DATABASE CreateTable ( void );
 
    void AddField ( DATABASE );
 
    void ShowTable ( DATABASE );
 
    void SortTable ( DATABASE );
 
    void DeleteTable ( DATABASE );
};
 
 
#endif _TASK2_H_


Task1.cpp

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
#include "Task2.h"
 
#include <memory>
 
TeamResult::DATABASE TeamResult::CreateTable ( void )
{
    return ( DATABASE ) malloc ( sizeof ( TR ) );
}
 
void TeamResult::AddField ( DATABASE db )
{
    puts ( "Input day: " );
    scanf ( "%s", &( db + fieldCnt - 1 )->day );
    puts ( "Input plan: " );
    scanf ( "%f", &( db + fieldCnt - 1 )->plan );
    puts ( "Input actual output: " );
    scanf ( "%f", &( db + fieldCnt - 1 )->realDo );
 
    double planPct = (
        ( db + fieldCnt - 1 )->plan ) /
        ( ( db + fieldCnt - 1 )->realDo ) * 100;
 
    if ( fieldCnt == 1)
    {
        planPctMax = planPct;
        planPctMin = planPct;
    }
    else 
    {
        if ( planPctMax < planPct ) 
            planPctMax = planPct;
        if ( planPctMin > planPct )
            planPctMin = planPct;
    }
 
    db = ( DATABASE ) realloc ( db, ( ++fieldCnt ) * sizeof ( FIELD ) );
}
 
void TeamResult::ShowTable ( DATABASE db )
{
    for ( int i = 0; i < fieldCnt - 1 ; ++i)
        cout<<( db + i )->plan<<endl;
}
 
void TeamResult::SortTable ( DATABASE db )
{
    for(int i = 0; i < fieldCnt - 1; ++i)
        for(int j = i + 1; j < fieldCnt - 1; ++j)
            if( ( ( db + i )->plan) > ( ( db + j )->plan) )
            {
                DATABASE tmp = new FIELD;
                memcpy ( tmp, ( db + i ), sizeof ( FIELD ) );
                memcpy ( ( db + i ), (db + j), sizeof ( FIELD ) );
                memcpy ( ( db + j ), tmp, sizeof ( FIELD ) );
                delete tmp;
            }
}
 
void TeamResult::DeleteTable ( DATABASE db )
{
    free ( db );
}


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
#include "Task2.h"
 
using namespace TeamResult;
 
int main()
{
 
    DATABASE db;
 
    db = CreateTable ( );
 
    AddField ( db );
 
    AddField ( db );
 
/////////////////////////////////////////
 
    AddField ( db );
 
    SortTable ( db );
 
    ShowTable ( db );
 
    DeleteTable ( db );
 
    system ( "pause" );
 
    return 0;
}
После второго раза вызова функции "ОС инициализировала точку останова", которая вызвана повреждением кучи.
C++
1
    db = ( DATABASE ) realloc ( db, ( ++fieldCnt ) * sizeof ( FIELD ) );
Как этого можна избежать?

Когда писал функцию заполнял только поле plan и все работало полностью.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.10.2012, 04:30
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Повреждение кучи (C++):

Повреждение кучи - C++
Приветствую! Сделал, казалось бы, простую программу, но у меня возникает ошибка на самом ровном месте: void print(node** graph, int V) ...

Повреждение кучи - C++
После выполнения программы выдаёт ошибку Debug Assertion Failed Помогите найти и исправить место из-за которого ошибка, я так понимаю она...

Повреждение кучи - C++
Есть код #include &lt;iostream&gt; using namespace std; struct STUDENT { char NAME; int GROUP; int SES; };

Ошибка о повреждение кучи - C++
Вот переделал программу со строками, с использованием классов. Почему-то опять возникает ошибка о повреждение кучи. Не могу понять где...

МНК, повреждение кучи - C++
Аппроксимация методом наименьших квадратов.. Если не использовать динамическую память, все работает замечательно.. Если описывать...

Странное повреждение кучи - C++
Доброго времени суток, форумчане! Есть проект, в нем реализована функцию дублирования всех элементов статического массива с...

4
Croessmah
Эксперт CЭксперт С++
13430 / 7585 / 857
Регистрация: 27.09.2012
Сообщений: 18,677
Записей в блоге: 3
Завершенные тесты: 1
17.10.2012, 05:00 #2
1)
C++
1
db = ( DATABASE ) realloc ( db, ( ++fieldCnt ) * sizeof ( FIELD ) );
Здесь db - это временный объект. В результате после первого вызова у Вас создается новый кусок памяти, а старый(который создавался в CreateTable()) удаляется, но указатель в функции main будет указывать на старый кусок.
сам указатель db(локальный) выделен на стеке и уничтожается после выхода из области видимости.
Чтобы не менять код внутри функции, передавайте этот параметр по ссылке:
void TeamResult::AddField ( DATABASE &db )

2)"%f" - это float, а у Вас double, поэтому используйте "%lf"
C++
1
scanf ( "%f", &( db + fieldCnt - 1 )->plan );
0
bytephone32
1 / 1 / 0
Регистрация: 08.08.2012
Сообщений: 21
17.10.2012, 05:19  [ТС] #3
Цитата Сообщение от Croessmah Посмотреть сообщение
Здесь db - это временный объект.
Как это временый? Я в функцию я передаю указатель на обьект, т.е. все что я сделаю с ним в функции касаеться и передаваемого параметра к примеру:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void SomeFunc(int* p)
{
    for ( int i = 0; i < 10; ++i)
        *(p+i) = i;
}
 
int main()
{
    int* k = new int[10];
 
    
    for ( int i = 0; i < 10; ++i)
        cout<<*(k+i);
 
    SomeFunc(k);
 
    for ( int i = 0; i < 10; ++i)
        cout<<*(k+i);
 
    system ( "pause" );
 
    return 1;
}

Цитата Сообщение от Croessmah Посмотреть сообщение
"%f" - это float, а у Вас double, поэтому используйте "%lf"
Это разве влияет на работоспособность? Мне бы сначала память нормально выделить, а потом эти функции будут заменены.
0
Croessmah
Эксперт CЭксперт С++
13430 / 7585 / 857
Регистрация: 27.09.2012
Сообщений: 18,677
Записей в блоге: 3
Завершенные тесты: 1
17.10.2012, 05:51 #4
Если ссылки не нравятся, тогда можно сделать через указатель:
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
void TeamResult::AddField ( DATABASE  * db )
{
    puts ( "Input day: " );
    scanf ( "%s", &( *db + fieldCnt - 1 )->day );
    puts ( "Input plan: " );
    scanf ( "%lf", &( *db + fieldCnt - 1 )->plan );
    puts ( "Input actual output: " );
    scanf ( "%lf", &( *db + fieldCnt - 1 )->realDo );
 
    double planPct = (
        ( *db + fieldCnt - 1 )->plan ) /
        ( ( *db + fieldCnt - 1 )->realDo ) * 100;
 
    if ( fieldCnt == 1)
    {
        planPctMax = planPct;
        planPctMin = planPct;
    }
    else 
    {
        if ( planPctMax < planPct ) 
            planPctMax = planPct;
        if ( planPctMin > planPct )
            planPctMin = planPct;
    }
 
    *db = ( DATABASE ) realloc ( *db, ( ++fieldCnt ) * sizeof ( FIELD ) );
}
Соответственно и объявление функции нужно поменять. И вызывать данную функцию так
AddField ( &db );

Добавлено через 2 минуты
Цитата Сообщение от bytephone32 Посмотреть сообщение
Как это временый? Я в функцию я передаю указатель на обьект, т.е. все что я сделаю с ним в функции касаеться и передаваемого параметра к примеру:
Вы передаете указатель на объект и можете изменять объект, а чтобы изменить указатель, Вам необходимо передать указатель на указатель (либо ссылку на указатель)

что касается scanf'a то влияет и очень сильно. если сделать "%f" для аргумета double, то в него запишется непонятное число, точнее понятное, но не ожидаемое

Добавлено через 12 минут

Не по теме:

Если что-то не понятно из вышесказанного то пишите. Я просто рассказчик замечательный, описываю слона, а получается крокодил =)))



Добавлено через 16 минут
Чтобы было понятнее, небольшой пример:
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
#include <iostream>
 
void Demo1(int * p1, int * p2){
    std::cout<<"\tDemo1 function\n";
    p2=p1;
}
void Demo2(int ** p1, int **p2){
    std::cout<<"\tDemo2 function\n";
    *p2=*p1;
}
 
int main ()
{
    int Num=10;
    int * pNum1=&Num;
    int * pNum2=NULL;
    std::cout.setf(std::ios_base::hex);
        std::cout<<"Main Function Start"<<std::endl;
    std::cout<<"pNum1 = "<<pNum1<<std::endl;
    std::cout<<"pNum2 = "<<pNum2<<std::endl;
        Demo1(pNum1,pNum2);
    std::cout<<"pNum1 = "<<pNum1<<std::endl;
    std::cout<<"pNum2 = "<<pNum2<<std::endl;
        Demo2(&pNum1,&pNum2);
    std::cout<<"pNum1 = "<<pNum1<<std::endl;
    std::cout<<"pNum2 = "<<pNum2<<std::endl;
    system ("pause");
    return 0;
}
2
bytephone32
1 / 1 / 0
Регистрация: 08.08.2012
Сообщений: 21
18.10.2012, 19:28  [ТС] #5
Croessmah, но в данном случае память будет выделяться последовательно? Каждая структура будет размещаться сразу же за предыдущей структурой?

Может будет безопаснее создать, так:

C++
1
2
typedef TR* FIELD;
typedef TR** DATABASE;
в DATABASE будет хранится адрес на FIELD на структуру. в Самом FIELD уже адрес самой структуры.

Добавлено через 35 минут
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
#include <memory>
 
 
typedef void* FIELD;
typedef void** DATABASE;
 
static int fieldCnt = 0;
 
struct TR
{
    int i;
    int k;
};
 
// Create table of database
DATABASE CreateTable ( void );
 
//Add field
void AddField ( DATABASE& );
 
int main()
{
    DATABASE db;
 
    db = CreateTable ( );
 
    AddField(db);
    AddField(db);
    AddField(db);
    AddField(db);
 
    cout<<((TR*)db + fieldCnt)->i;
 
    //ShowTable ( db );
 
    //DeleteTable ( db );
 
    system("pause");
    return 0;
}
 
DATABASE CreateTable ( void )
{
    return (DATABASE) malloc ( sizeof ( FIELD ) );
}
 
void AddField ( DATABASE& db )
{
    //aloccated memory for our struct in last field;
    *(db + fieldCnt) = (TR*) malloc ( sizeof ( TR ) );
    //input data
    printf ( "Input day: " );
    scanf ( "%d", &((TR*)db + fieldCnt)->i );
    //
        //как тут нам расширить память для указателей для структур???
    *db = ( FIELD ) realloc ( *db, ( ++fieldCnt + 1 ) * sizeof ( FIELD ) );
}
Добавлено через 20 минут
т.е. в db всегда должен хранится адресс на первый байт массива указателей на структуры, и должен равнятся всегда одному значению, которое ему досталось после выполнения функции CreateTable ( );
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.10.2012, 19:28
Привет! Вот еще темы с ответами:

Точка останова(повреждение кучи) - C++
Прошу помочь, смотрел по форуму похожие темы - ответа не нашел void Base::Read() { char* name=new char;//переменная для имени ...

C++ delete[] точка останова/повреждение кучи - C++
Добрый день. Подскажите, пожалуйста. Вот код функции: void interpol(point* a, int n, int k, point* y, int inter) //a-original ...

Повреждение кучи при создании нейросети с количеством слоев больше 51 - C++
Добрый день. Я знаю, таких тем уже много, я их прочитала, но ни в одной не нашла решения моей проблемы. Проблема. Есть нейронная сеть...

Ошибка при "сборе мусора" . Повреждение кучи - C++
Привет ребята! Я совсем скверно знаю плюсы и не смотря на несколько лет довольно успешной работы в ИТ так и не заставил себя заниматься...


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

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

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