Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Assert failure, Block type is valid 
:(
    Опции темы
jimbo
Дата 8.9.2009, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 18.6.2009
Где: Южно-Сахалинск

Репутация: нет
Всего: нет



Привет всем. 

У меня следующий вопрос. 

вот кусок кода

Код

class MyClass A;
char* str = A.func();
if(strlen(str)!=A.size)
{
if(str)
{
delete []str;
str = NULL;
str = new char[20];
}
}
.....

if(str)
{
delete []str;
str = NULL;
}




При повторном возвращении к этому коду в одном процессе это вызывет ошибку BLOCK_TYPE_IS_VALID и т.д. 

Я исправил ее путем замены кода на
Код

class MyClass A;
char* str = A.func();
if(strlen(str)!=A.size)
{
str = new char[20];
}
.....

if(str)
{
delete []str;
str = NULL;
}


то есть была ошибка повторного удаления буфера. Поясняю, в моей функции класса, она рекурсивна, считался путь к файлу. Результат записывался в A.buf. Проверка длин происходит в том случае, если файл моя функция не нашла. Деструктор класса написан так:

Код

A::~A()
{
if(this->buf)
{
delete []this->buf;
this->buf = NULL;
}
}



Отсюда вопрос - почему ошибка исправилась и вообще почему она происходила, если в обоих случаях удаления буфера была проверка на ноль? Или при удалении экземпляра класса помимо деструктора вызывается еще что-то системное, не знающее что уже буфер удалеН?
--------------------
Я не играю в шахматы - в шахматах я борюсь. А.А.Алехин
PM MAIL WWW   Вверх
Anikmar
Дата 8.9.2009, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 5
Всего: 59



На вскидку (не видя всего вцелом):
При повторном обращение к коду если str == NULL
код
if(strlen(str)!=A.size) может вызвать нарушение доступа

PM MAIL ICQ   Вверх
jimbo
Дата 10.9.2009, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 18.6.2009
Где: Южно-Сахалинск

Репутация: нет
Всего: нет



Спасибо за ответ!

strlen(str) присутствует в обеих частях кода, и работающего и неработающего. И это также отсекается тем, что фуункция .func() не возвращает ноль никогда.
--------------------
Я не играю в шахматы - в шахматах я борюсь. А.А.Алехин
PM MAIL WWW   Вверх
Anikmar
Дата 10.9.2009, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 5
Всего: 59



Тогда другое предположение:
strlen вызывается к "мусорной" строке, что тоже бывает не очень хорошо.

Кстати, а зачем явно указывать this?
PM MAIL ICQ   Вверх
jimbo
Дата 14.9.2009, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 18.6.2009
Где: Южно-Сахалинск

Репутация: нет
Всего: нет



метод класса func  не возвращает 0 никогда=(
--------------------
Я не играю в шахматы - в шахматах я борюсь. А.А.Алехин
PM MAIL WWW   Вверх
Anikmar
Дата 14.9.2009, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 5
Всего: 59



А как выделяет память метод func?
PM MAIL ICQ   Вверх
Acer
Дата 14.9.2009, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: нет
Всего: 8



func() возвращает указатель на buf ?

Добавлено через 12 минут и 33 секунды
Сначала удаляется память, на которую указывает str
Код

delete [] str;

(до деструктора), а потом в деструкторе попытка очистить ту же самую область памяти
Код

delete [] buf;

В данном случае лучше делать так(если я правильно понял)
Код

const int size = 1024; //нужный размер буфера
char str[size];
strcpy_s( str, size, A.func() );

PM MAIL   Вверх
bsa
Дата 14.9.2009, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



jimbo,  из твоего кода мало что понятно. Кроме того, что скорее всего ты изменил верный вариант на неверный. Представь содержимое метода MyClass::func().

Почему не воспользовался std::string?
PM   Вверх
jimbo
Дата 28.9.2009, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 180
Регистрация: 18.6.2009
Где: Южно-Сахалинск

Репутация: нет
Всего: нет



Код

char* MyClass::FindFileOnServer(char* filename)
{
    //printf("%s\n",filename);
    //this->buf;//filename
    int i=0;
    int j=0;
    /*while(this->buf[i]!=0) i++;
    char* tmp = new char[i+1];
    strcpy(tmp,this->buf);
    tmp[i]=0;*/
    HANDLE hFind = INVALID_HANDLE_VALUE;
    char string[MAX_PATH];
    WIN32_FIND_DATA winData;
    //DWORD dwError;
    //pack *tmp;
    strcpy( string, filename ); 
    strcat( string, "\\*");
    hFind = FindFirstFile(string, &winData);
    if (hFind != INVALID_HANDLE_VALUE) 
    {
        while (FindNextFile(hFind,&winData)!=0)
        {
            if(strcmp(winData.cFileName,"..")==0) continue;
            if(winData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
            {
                char* string2 = new char[(int)strlen(filename)+(int)strlen("\\")+(int)strlen(winData.cFileName)+1];
                strcpy(string2,filename);
                strcat(string2,"\\");
                strcat(string2,winData.cFileName);
                //tmp = this;
                //delete []tmp;
                char* tmp = this->FindFileOnServer(string2);
                /*this->buf = this->FindFileOnServer(string2);*/
                if(0!=strcmp(this->buf,tmp)) 
                {
                    delete []string2;
                    string2=NULL;
                    //delete []tmp;
                    //tmp = new char[(int)strlen(this->buf)+1];
                    //strcpy(tmp,this->buf);
                    //tmp[(int)strlen(tmp)]=0;
                    FindClose(hFind);
                    return tmp;
                }
                if(string2) {delete []string2;string2 = NULL;}
                //if(tmp) {delete []tmp;tmp=NULL;}
            }
            j=0;
            while(this->buf[j]!='.')
                if(this->buf[j]!=winData.cFileName[j]) break;
                else j++;
            if(winData.cFileName[j]=='.' && this->buf[j] == '.')
            {
                char* file = new char[(int)strlen(filename)+(int)strlen("\\")+(int)strlen(winData.cFileName)+1];
                strcpy(file,filename);
                strcat(file,"\\");
                strcat(file,winData.cFileName);
                //if(tmp) {delete []tmp;tmp=NULL;}
                //if(string2) {delete []string2;string2=NULL;}
                FindClose(hFind);
                return file;            //провериьт
            }
        }
    }
//    delete []tmp;
//    tmp = NULL;
    FindClose(hFind);
    return this->buf;
    /*delete []tmp;
    tmp = new char[(int)strlen(this->buf)+1];
    strcpy(tmp,this->buf);
    tmp[(int)strlen(tmp)]=0;
    return tmp;*/
}


FindFileOnServer - это есть "из примера" MyClass::func();


string я потом использовать подумалsmile 

Но вопрос решен. Я че-то протупил жестко и уже даже когда писал пример!

То что происходило удаление два раза я знал. я не понимал откуда оно, теперь все ясно.

была одна область памяти и 2 указателя на нее.. и сначала я удалял по одному указателю, потом по второму - СПАСИБО Acer!! Как я сам не увидел - фиг знает))



Anikmar 
к мусорной строке strlen обращаться никак не может - это видно по возвращаемому значению MyClass::func();

Использую this я, потому что если много членов в классе, студия находит нужный по нескольким первым символам - не приходится полностью писать. (ctrl+пробел). А так не вижу разницы указывать this или нет, может код будет лучше пониматься путем отделения членов класса и локальных переменных.

Это сообщение отредактировал(а) jimbo - 28.9.2009, 15:04
--------------------
Я не играю в шахматы - в шахматах я борюсь. А.А.Алехин
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0536 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.