Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
 Аватар для lordimid
6 / 5 / 1
Регистрация: 02.10.2011
Сообщений: 111

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

24.03.2016, 16:49. Показов 2551. Ответов 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)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.03.2016, 16:49
Ответы с готовыми решениями:

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

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

Динамическое выделение памяти под массив
Здравствуйте! Помогите разобраться.Сама программа есть, но без массива.Не могу сообразить как сделать. Задание: Вывести на печать все...

7
694 / 304 / 99
Регистрация: 04.07.2014
Сообщений: 851
24.03.2016, 17:44
Цитата Сообщение от lordimid Посмотреть сообщение
то компилятор, когда доходит до точки delete pan;
Тут и ошибка, для массива должно быть
C++
1
            delete [] pan;
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,218
24.03.2016, 18:48
Бессмысленно гадать, где у вас в коде ошибка, пока вы не приведете мало-мальски осмысленный кусок кода. Что такое prsAnnouncments? Почему в вашем посте не видно полного детального объявления этого типа?

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

И, как уже было сказано, удаление массивов в С++ делается через delete [].
0
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
24.03.2016, 19:01
Цитата Сообщение от lordimid Посмотреть сообщение
то компилятор, когда доходит до точки delete pan;
lordimid, как минимум, несоответствие new и delete
0
 Аватар для lordimid
6 / 5 / 1
Регистрация: 02.10.2011
Сообщений: 111
25.03.2016, 09:55  [ТС]
Извиняюсь. Вот более развернутая версия моего примера.


файл 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
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12937 / 6804 / 1821
Регистрация: 18.10.2014
Сообщений: 17,218
25.03.2016, 11:24
Лучший ответ Сообщение было отмечено lordimid как решение

Решение

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

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

P.S. В каком это новом стандарте С++ вы усмотрели разрешение не указывать [] в delete - я не знаю. Ничего подобного там нет.
1
Неэпический
 Аватар для Croessmah
18146 / 10730 / 2066
Регистрация: 27.09.2012
Сообщений: 27,029
Записей в блоге: 1
25.03.2016, 11:46
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В каком это новом стандарте С++ вы усмотрели разрешение не указывать [] в delete - я не знаю.
Наверное, мы просто все отстали от жизни
0
 Аватар для lordimid
6 / 5 / 1
Регистрация: 02.10.2011
Сообщений: 111
25.03.2016, 17:05  [ТС]
TheCalligrapher
Да вы правы, я перепутал. Это размер массива не нужно указывать в скобках после delete [].
Спасибо за подсказку, что-то у меня глаз замылился. Действительно проблема была в том, что я выходил за пределы массива. Блин надо же было на таком пустяке два дня убить. Еще раз благодарю.
PS
А по поводу того, что я немного функцию изменил, то это не обмана ради. Просто у меня одинаковая ошибка появлялась, поэтому я и выложил последний вариант этой функции. Так что не серчайте, обманывать я вас не хотел .
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.03.2016, 17:05
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru