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

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

24.03.2016, 16:49. Просмотров 1162. Ответов 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
Ответы с готовыми решениями:

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

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

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

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

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

7
AlexVRud
483 / 194 / 73
Регистрация: 04.07.2014
Сообщений: 547
24.03.2016, 17:44 2
Цитата Сообщение от lordimid Посмотреть сообщение
то компилятор, когда доходит до точки delete pan;
Тут и ошибка, для массива должно быть
C++
1
            delete [] pan;
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4848 / 2492 / 696
Регистрация: 18.10.2014
Сообщений: 4,326
24.03.2016, 18:48 3
Бессмысленно гадать, где у вас в коде ошибка, пока вы не приведете мало-мальски осмысленный кусок кода. Что такое prsAnnouncments? Почему в вашем посте не видно полного детального объявления этого типа?

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

И, как уже было сказано, удаление массивов в С++ делается через delete [].
0
Croessmah
++Ͻ
15236 / 8626 / 1640
Регистрация: 27.09.2012
Сообщений: 21,242
Записей в блоге: 2
Завершенные тесты: 1
24.03.2016, 19:01 4
Цитата Сообщение от lordimid Посмотреть сообщение
то компилятор, когда доходит до точки delete pan;
lordimid, как минимум, несоответствие new и delete
0
lordimid
5 / 4 / 1
Регистрация: 02.10.2011
Сообщений: 107
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Эксперт С++
4848 / 2492 / 696
Регистрация: 18.10.2014
Сообщений: 4,326
25.03.2016, 11:24 6
Лучший ответ Сообщение было отмечено lordimid как решение

Решение

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

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

P.S. В каком это новом стандарте С++ вы усмотрели разрешение не указывать [] в delete - я не знаю. Ничего подобного там нет.
1
Croessmah
++Ͻ
15236 / 8626 / 1640
Регистрация: 27.09.2012
Сообщений: 21,242
Записей в блоге: 2
Завершенные тесты: 1
25.03.2016, 11:46 7
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В каком это новом стандарте С++ вы усмотрели разрешение не указывать [] в delete - я не знаю.
Наверное, мы просто все отстали от жизни
0
lordimid
5 / 4 / 1
Регистрация: 02.10.2011
Сообщений: 107
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 и его размер. Функция...

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


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

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

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