Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
lordimid
3 / 3 / 3
Регистрация: 02.10.2011
Сообщений: 101
#1

Динамическое выделение памяти под массив структур (new/delete) - C++

24.03.2016, 16:49. Просмотров 483. Ответов 7
Метки нет (Все метки)

Люди добрые, подскажите пожалуйста, где в моем коде закралась ошибка? Интернет перечитал, во всех примерах код, подобный моему работает, а у меня почему то нет. Не работает следующая функция:

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
prsAnnouncments *wifunctions::prsFindAnnouncments(TCHAR *prsPageSource)
{
    TCHAR *lpPage;   // Указатель на текущее положение в странице
    lpPage=prsPageSource;
    prsStrings *lppsi,psi;
    lppsi=ψ 
    prsStringsInit(lppsi);
    prsAnnouncments *PanTemp,*pan;
 
    int i=0;
    do
    {
        if(i>0)
        {
            pan = new prsAnnouncments[i];
        //  pan = prsCopyAnnounceStructs(pan,PanTemp,i);
            delete  PanTemp;
 
        }
        else
            pan = new prsAnnouncments;
 
        lpPage=prsFindString(lppsi->TextAdress,lpPage);                              
    //  lpPage=prsCopyStringToAnn(L'"',lpPage,(pan+i)->AnAddr);                      
        wcscpy(pan->AnAddr,L"DFfdsfdsfdsfdsf3443543лдодл");
 
        if(i>0)
        {
            PanTemp = new prsAnnouncments[i];
        //  PanTemp=prsCopyAnnounceStructs(PanTemp,pan,i+1);
 
            delete  pan;
        }else
        {
            PanTemp = new prsAnnouncments;
        //  *PanTemp=*pan;
        //  wcscpy_s(PanTemp->AnAddr,pan->AnAddr);
            delete pan;
        }
        
        i++;
    }while(true);
    return pan;
}
Дело в том, что когда я вызываю функцию
C++
1
        wcscpy(pan->AnAddr,L"DFfdsfdsfdsfdsf3443543лдодл");
то компилятор, когда доходит до точки delete pan;

C++
1
2
3
4
5
6
7
        if(i>0)
        {
            PanTemp = new prsAnnouncments[i];
        //  PanTemp=prsCopyAnnounceStructs(PanTemp,pan,i+1);
 
            [B]delete  pan;[/B]
        }else
выкидывает меня на кусок кода:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void __cdecl _free_base (void * pBlock)
{
 
        int retval = 0;
 
 
        if (pBlock == NULL)
            return;
 
        RTCCALLBACK(_RTC_Free_hook, (pBlock, 0));
 
        retval = HeapFree(_crtheap, 0, pBlock);
        if (retval == 0)
        {
            errno = _get_errno_from_oserr(GetLastError());
        }
}
(файл free.c) и замирает.
В чем дело, подскажите пожалуйста? Что я делаю не так? Вся суть в том, что если элемент массива структур больше нуля, то при присвоении ему строки, память почему-то освобождается с ошибками. Если функцию
C++
1
        wcscpy(pan->AnAddr,L"DFfdsfdsfdsfdsf3443543лдодл");
убрать из кода, то ошибок не возникает.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.03.2016, 16:49
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Динамическое выделение памяти под массив структур (new/delete) (C++):

Динамическое выделение памяти под массив
Я хочу функцию использовать пару раз, количество команд будет уменьшаться, и...

Динамическое выделение памяти под массив
Доброго времени суток. Как реализовать динамическое выделение памяти под...

Выделение памяти под массив структур
Добрый день. Подскажите в чём ошибка. #pragma hdrstop #pragma argsused...

Выделение памяти под массив структур
Возникла проблема в том что не могу никак эфективно реализовать выделение...

Динамическое выделение памяти под двумерный массив
Нужно написать программу, динамически выделяем память под двумерный массив,...

Динамическое выделение памяти под двумерный массив
1) Ввести построчно элементы двумерного массива чисел. Количество столбцов...

7
AlexVRud
477 / 189 / 72
Регистрация: 04.07.2014
Сообщений: 530
24.03.2016, 17:44 #2
Цитата Сообщение от lordimid Посмотреть сообщение
то компилятор, когда доходит до точки delete pan;
Тут и ошибка, для массива должно быть
C++
1
            delete [] pan;
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4372 / 2347 / 654
Регистрация: 18.10.2014
Сообщений: 3,996
24.03.2016, 18:48 #3
Бессмысленно гадать, где у вас в коде ошибка, пока вы не приведете мало-мальски осмысленный кусок кода. Что такое prsAnnouncments? Почему в вашем посте не видно полного детального объявления этого типа?

Разумеется, угадать "на кофейной гуще", что именно у вас там происходит труда не составит - ваша wcscpy переполняет целевой буфер, рушит динамическую память и все потом падает. Но тем не менее - потрудитесь постить код целиком.

И, как уже было сказано, удаление массивов в С++ делается через delete [].
0
Croessmah
++Ͻ
14158 / 8083 / 1513
Регистрация: 27.09.2012
Сообщений: 19,921
Записей в блоге: 3
Завершенные тесты: 1
24.03.2016, 19:01 #4
Цитата Сообщение от lordimid Посмотреть сообщение
то компилятор, когда доходит до точки delete pan;
lordimid, как минимум, несоответствие new и delete
0
lordimid
3 / 3 / 3
Регистрация: 02.10.2011
Сообщений: 101
25.03.2016, 09:55  [ТС] #5
Извиняюсь. Вот более развернутая версия моего примера.


файл maincode.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
63
64
65
66
67
68
69
70
71
72
#include "resource.h"
wifunctions wifunc,*wfi;
 
int TmpInt;
extern ParseConfigs apc,*lpapc;
 
 
 
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInstance,LPSTR lpszCmdLine,int CmdShow)
{
    MSG msg;
    wfi=&wifunc;
 
.....................................
 
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
 
 
LRESULT CALLBACK MainWindowFunction(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    wfi=&wifunc;
    switch(msg) 
    {
 
......................................................................
 
 
    case WM_COMMAND:
        {
            switch(LOWORD(wParam))
            {
 
                case ID_SEND:
                    {
                        wfi=&wifunc;
                        CreateThread(NULL,0,ParseThread,(LPVOID)NULL,0,&(wfi->dwIDThread));
                        return 0;
                    }
            }
 
            return 0;
        }
 
......................................................................
 
    case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 0;
        }
    }
    return DefWindowProc(hwnd,msg,wParam,lParam);
}
 
 
DWORD WINAPI ParseThread(LPVOID cnt)
{
    wfi=&wifunc;
......................................................................
 
wfi->prsFindAnnouncments(PageUTF);
 
......................................................................
 
    return 0;
}

файл resource.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
37
38
39
#include <Tchar.h>
//#include <Shlwapi.h>
#include <windows.h>
#include <windowsx.h>
#include <Winbase.h>
#include <iostream>
#include <fstream>
#include <commctrl.h>
#include <WinInet.h>
#pragma comment(lib,"wininet")
 
................................................................................................ 
 
extern HWND wihw,wiEdit,hwHost,hwSend,hwDlgOptions,hwDlgEdit;
extern HINSTANCE hInstance;
 
................................................................................................ 
 
DWORD WINAPI ParseThread(LPVOID);
 
LRESULT CALLBACK MainWindowFunction(HWND,UINT,WPARAM,LPARAM);
 
struct prsAnnouncments 
{
    int AnMin,prsAnHr,prsAnY,prsAnMon,prsAnDay;          //
    TCHAR AnAddr[100];
    TCHAR AnTittle[100];
    TCHAR AnnDiscr[1000];
    int AnPrice;
};
 
................................................................................................ 
 
class wifunctions{
public:
................................................................................................ 
prsAnnouncments *prsFindAnnouncments(TCHAR *prsPageSource);   
................................................................................................ 
};
файл resourceopen.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
#include "resource.h"
................................................................................................ 
 
prsAnnouncments *wifunctions::prsFindAnnouncments(TCHAR *prsPageSource)
{
    TCHAR *lpPage;   // Указатель на текущее положение в странице
    lpPage=prsPageSource;
    prsAnnouncments *PanTemp,*pan;
 
    int i=0;
    do
    {
        if(i>0)
        {
            pan = new prsAnnouncments[i];
        //  pan = prsCopyAnnounceStructs(pan,PanTemp,i);
            if(i==1)
                delete  PanTemp;
            else
                delete[] PanTemp;
 
        }
        else
            pan = new prsAnnouncments;
 
        lpPage=prsFindString(lppsi->TextAdress,lpPage);                                  // Сначала ищем адрес обьявления
    //  lpPage=prsCopyStringToAnn(L'"',lpPage,(pan+i)->AnAddr);                         // Копируем его в структуру prsAnnouncments
        wcscpy((pan+i)->AnAddr,L"DFfdsfdsfdsfdsf3443543лдодл");
 
        if(i>0)
        {
            PanTemp = new prsAnnouncments[i];
        //  PanTemp=prsCopyAnnounceStructs(PanTemp,pan,i+1);
 
            delete[]  pan;
        }else
        {
            PanTemp = new prsAnnouncments;
        //  *PanTemp=*pan;
            wcscpy_s(PanTemp->AnAddr,pan->AnAddr);
            delete pan;
        }
        
        i++;
    }while(true);
    return pan;
}
................................................................................................
По новому стандарту С++ на сколько я знаю указывать [] после delete необязательно. Пробовал со скобками и без них - результат тот же.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4372 / 2347 / 654
Регистрация: 18.10.2014
Сообщений: 3,996
25.03.2016, 11:24 #6
Лучший ответ Сообщение было отмечено lordimid как решение

Решение

Ну так значит в первой версии кода вы нас просто обманывали? Там доступ в wcscpy ведется через pan, а здесь вдруг стало pan+i. Что это за неожиданные различия? В чем дело?

В последнем варианте все ясно: вы выделяете масив размера i, а потом доступаетесь к элементу pan+i - это очевидный выход за пределы массива. Потому все и падает.

P.S. В каком это новом стандарте С++ вы усмотрели разрешение не указывать [] в delete - я не знаю. Ничего подобного там нет.
1
Croessmah
++Ͻ
14158 / 8083 / 1513
Регистрация: 27.09.2012
Сообщений: 19,921
Записей в блоге: 3
Завершенные тесты: 1
25.03.2016, 11:46 #7
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В каком это новом стандарте С++ вы усмотрели разрешение не указывать [] в delete - я не знаю.
Наверное, мы просто все отстали от жизни
0
lordimid
3 / 3 / 3
Регистрация: 02.10.2011
Сообщений: 101
25.03.2016, 17:05  [ТС] #8
TheCalligrapher
Да вы правы, я перепутал. Это размер массива не нужно указывать в скобках после delete [].
Спасибо за подсказку, что-то у меня глаз замылился. Действительно проблема была в том, что я выходил за пределы массива. Блин надо же было на таком пустяке два дня убить. Еще раз благодарю.
PS
А по поводу того, что я немного функцию изменил, то это не обмана ради. Просто у меня одинаковая ошибка появлялась, поэтому я и выложил последний вариант этой функции. Так что не серчайте, обманывать я вас не хотел .
0
25.03.2016, 17:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.03.2016, 17:05
Привет! Вот еще темы с решениями:

Динамическое выделение памяти под двумерный массив
Здравствуйте. Как мне правильно и грамотно (!) выделять память под двумерные...

Динамическое выделение памяти под массив int
плиз хелп Написать функцию getPrimes, которая принимает массив типа int и его...

Выделение динамической памяти под массив структур
Добрый день, уважаемые! Пишу функцию выделения памяти под массив структур. Но...

Выделение динамической памяти под массив структур
Здравствуйте! Пытаюсь выделить память под массив структур, считать с...


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

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

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