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

C++ Builder

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 23, средняя оценка - 4.91
Yak
0 / 0 / 0
Регистрация: 16.02.2009
Сообщений: 8
#1

Ошибка удаления дин. массива AnsiString - C++ Builder

16.02.2009, 11:49. Просмотров 2842. Ответов 15
Метки нет (Все метки)

Здравствуйте! Меня уже несколько лет приследует одна и та же проблема, которой я не могу найти решение.
Вкратце: при удалении динамического массива элементов AnsiString иногда возникает исключение "Access violation".
Более подробно это выглядит так:
Периодически возникает необходимость использовать массивы элементов, в каждом из которых есть AnsiString. Это может быть, как массив AnsiString, так массив структур, в которых есть тот же AnsiString. Для таких массивов я пишу объекты по принципу написал-отладил-зыбыл. После отладки объекта я продолжаю писать другие модули программы и вдруг ни с того, ни с сего возникает исключение на операторе delete в том самом отлаженном объекте, к которому я уже неделю не прикасаюсь. Промучившись с этим исключением два дня и ничего не решив я обычно плюю и за час переделываю все эти гребаные АнсиСтринги в char *. Только после этого я действительно забываю об объекте, потому что он начинает работать, как часы и, к тому же, быстрее. Проблема в том, что я не могу отловить эту ситуацию. Я не понимаю, почему это может происходить и как с этим бороться. Это происходит лишь иногда. Да, да! В это сложно поверить, я знаю, но жестко зафиксировать глюк не удается. Разговоры о "вылезании" за пределы выделенной памяти лишены всякого смысла, т.к. если бы у меня не было достаточно опыта, то с массивами char * я бы уж точно вылез за пределы, а с ними проблем нет. К примеру в одной из программ у меня было выделение памяти для 6 элементов AnsiString (число элементов было фиксировано константой, но массив был динамический - так было нужно). Как обычно в один прекрасные день это все захлебнулось в исключениях. После бессонной ночи я, так и не решив проблему, изменил 6 на 7 и все тут же заработало. Этот проект работает и развивается до сих пор все с той же семеркой и без глюков. Только что появилась возможность "поймать" глюк и я могу привести код, который у меня не работает. После трех нажатий на кнопку Button1 (вызов Button1Click(TObject *Sender) возникает исключение. Строка исключения помечена примечанием.

P.S. Код элементарный. Не поленитесь прочитать.
Конкретно этот код тестировался на бесплатном Turbo C++, но похожие ошибки возникали и на 5 и на 6 Builder'е.

Код
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

struct SStruct{
 AnsiString Name;
 //any other defenitions
};
//---------------------------------------------------------------------------

class CClass{
 private:
  SStruct *Struct;
  int Size;
 public:
  void Add(AnsiString Name);
  void Clear();
  CClass();
  ~CClass();
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

void CClass::Add(AnsiString Name){
 SStruct *S=new SStruct[Size+1];
 for(int i=0;i<Size;i++)S[i]=Struct[i];
 if(Size)delete Struct; // Access violation
 S[Size++].Name=Name;
 Struct=S;
};
//---------------------------------------------------------------------------

void CClass::Clear(){
 if(Size)delete Struct;
 Size=0;
};
//---------------------------------------------------------------------------

CClass::CClass(){
 Size=0;
};
//---------------------------------------------------------------------------

CClass::~CClass(){
 Clear();
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

CClass *Class;

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
 Class=new CClass;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
 delete Class;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 Class->Add(Edit1->Name);
}
//---------------------------------------------------------------------------
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.02.2009, 11:49
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Ошибка удаления дин. массива AnsiString (C++ Builder):

из дин. дека в дин. стек (Borland С++) - C++ Builder
Доброй ночи. Никак не получается сделать из динамического дека - стек. Помогите разобраться где именно и что необходимо изменить, что бы...

Как перевести текст из AnsiString (в формате UTF8) в AnsiString формата Windows-1251? - C++ Builder
Поиск по форуму не решил текущую проблему: 1. Есть текст в формате UTF-8 в величине: AnsiString qw; Вопрос: 2. Как перевести текст в...

ошибка в dll с классом AnsiString - C++ Builder
Возникла такая проблема: при использовании во внутренних функциях dll типа AnsiString возникают различные Linker Error-ы, например...

Ошибка Cannot convert AnsiString to Bool - C++ Builder
void __fastcall TForm3::Edit1Change(TObject *Sender) { Button1-&gt;Enabled=Edit1-&gt;Text; }вот код, как исправить?

сортировка массива AnsiString - C++ Builder
подскажите как отсортировать массив AnsiString name не только по длине но и по алфавиту

Ошибка: E2034 Cannot convert 'TStrings' to 'AnsiString' - C++ Builder
когда программа запускается вылезает ошибка: E2034 Cannot convert 'TStrings' to 'AnsiString' for (int...

15
Yak
0 / 0 / 0
Регистрация: 16.02.2009
Сообщений: 8
17.02.2009, 09:36  [ТС] #16
Цитата Сообщение от Vourhey Посмотреть сообщение
то массив из одного элемента, то удалить его я могу
Цитата Сообщение от Vourhey Посмотреть сообщение
Русский тоже, вроде, правильный


Добавлено через 14 минут 9 секунд
Вчера потестил незамысловатую программу:
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
char ***C;
int a=100,b=1000,c=100;
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 C=new char**[a];
 for(int i=0;i<a;i++){
    C[i]=new char*[b];
    for(int k=0;k<b;k++)
       C[i][k]=new char[c];
 }
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 for(int i=0;i<a;i++){
    for(int k=0;k<b;k++)
       delete C[i][k];
    delete C[i];
 }
 delete C;
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button3Click(TObject *Sender)
{
 for(int i=0;i<a;i++){
    for(int k=0;k<b;k++)
       delete[] C[i][k];
    delete[] C[i];
 }
 delete[] C;
}
//---------------------------------------------------------------------------
Button2Click и Button3Click высвобождает одинаковое кол-во памяти с точностью до килобайта. Почему - не знаю. Видимо этого не знаю не я один. Потому что вразумительного объяснения никто не дал. Если следовать логике Vourhey, то оператор delete при удалении массива char *c=new char[1000] освободит 1 байт. На практике это не так.

P.S. Alexiski отдельное спасибо. Вопрос, озвученный в шапке темы решен с его помощью.
0
17.02.2009, 09:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.02.2009, 09:36
Привет! Вот еще темы с ответами:

AnsiString ошибка Multiple declaration for 'str' - C++ Builder
В идеале надо первое слово выкинуть с текста (матерное ;D) Вот я чет не пойму нифига, может подскажет кто... в начале все нормально с...

Ошибка cannon convert 'AnsiString' to 'char' - C++ Builder
Помогите. пожалуйста. Пишу программу, нужно записать название команды и ее баллы в массив, в коде Form1-&gt;mas.name=(Edit1-&gt;Text); ...

Ошибка при преобразовании AnsiString в char* - C++ Builder
TDateTime tt = DateTimePicker1-&gt;Date; char* proc_beggin_date = (DateToStr(tt)).c_str(); Почему в результате в строке proc_beggin_date...

Доступ к символу элемента массива AnsiString - C++ Builder
Здравствуйте! Как можно получить доступ к определенному символу элемента массива AnsiString'a? Например, у меня AnsiString mas ...


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

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

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