Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.03.2012, 14:22   #1
Agmentium78
 
Регистрация: 18.03.2012
Сообщений: 7
По умолчанию Конкретная ошибка конпелятора (С++)

Здравствуйте. Столкнулся с необъяснимым поведением программы: если закоментировать 33 строку в main.cpp, то программа работает нормально, если раскоментировать, то падает.

Но дело в том, что вызываемая там функция ничего не изменяет.

В архиве прилагаю код и экзешник(160 строк).

Компилятор MinGW, система Win7-x64.


Я не прошу писать за меня код, но пожалуйста, если вы разбираетесь в вопросе, то посмотрите и подскажите где там у меня ошибка.

P.S. Я в курсе что дважды создавать здесь темы нельзя, но я неправильно выбрал раздел. Приношу свои извинения и прошу удалить первую тему.
Вложения
Тип файла: rar Ask.rar (184.9 Кб, 11 просмотров)
Agmentium78 вне форума Ответить с цитированием
Старый 18.03.2012, 14:30   #2
S1av0k
Пользователь
 
Регистрация: 26.11.2009
Сообщений: 87
По умолчанию

Выложите тексты кодов, а не архив, используя тэги оформления .
Помог - жми весы
S1av0k вне форума Ответить с цитированием
Старый 18.03.2012, 14:32   #3
Agmentium78
 
Регистрация: 18.03.2012
Сообщений: 7
По умолчанию

Код с некоторым подобием комментариев.

main.cpp
Код:
#include <iostream>
#include "MyString.cpp"

using namespace std;

void mystr_dbg(MyString in){
    cout << "\tthis->length == " << in.get_len() << endl;

    if (in.get_str())
        cout << "\tthis->str == '" << in.get_str() << "'" << endl;

    cout << "\tthis->str " << (void *)in.get_str() << endl << endl;
}

int main(){
    MyString mystr_first;

    cout << "MyString mystr_first" << endl;
    mystr_dbg(mystr_first);


    MyString mystr_second = mystr_first;

    cout << "mystr_second = mystr_first" << endl;
    mystr_dbg(mystr_second);


    MyString mystr_third = MyString('a');

    cout << "mystr_third = 'a'" << endl;
    mystr_dbg(mystr_third);
    //ЕСЛИ ВЕРХНЮЮ ЗАКОМЕНТИРОВАТЬ ЭТУ СТРОКУ ВСЕ РАБОТАЕТ

    MyString mystr_four = MyString((char *)"abcd78");

    cout << "mystr_third = 'abcd78'" << endl;
    mystr_dbg(mystr_four);
}
MyString.cpp
Код:
/*MyString class definition

    #if DEBUG == 1
        cout << "\t[DBG] " << ;
    #endif

*/

//for strcpy
#include <string.h>

#define DEBUG 1

#if DEBUG == 1
    #include <iostream>
    using namespace std;
#endif

class MyString{
    protected:
        char *str;
        int length;

    public:
        MyString();
        MyString(char x);
        MyString(char *x);

        MyString(const MyString &obj);
        ~MyString();

        char *get_str() {return this->str;}
        int get_len() {return this->length;}

    protected:
        void set_values(char *x, int y);
        char *realloc(int size);
        void init();
};




/*Create an _empty_ string
*/
MyString::MyString(){
    #if DEBUG == 1
        cout << "\t[DBG] " << "MyString::MyString()" << endl;
    #endif

    char *tmp;

    init();

    tmp = realloc(0);
    tmp[0] = '\0';

    this->set_values(tmp, 0);
}



/**/
MyString::MyString(char *x){
    #if DEBUG == 1
        cout << "\t[DBG] " << "MyString::MyString(char *x)" << endl;
    #endif

    char *tmp;
    int x_length;

    init();

    x_length = strlen(x);
    tmp = this->realloc(x_length);

    strcpy(tmp, x);

    this->set_values(tmp, x_length);
}



/**/
MyString::MyString(char x){
    #if DEBUG == 1
        cout << "\t[DBG] " << "MyString::MyString(char x)" << endl;
    #endif

    char *tmp;

    init();

    tmp = realloc(1);

    tmp[0] = x;
    tmp[1] = '\0';

    this->set_values(tmp, 1);
}




/*Copy constructor.

Creates completely independent copy of &obj.*/
MyString::MyString(const MyString &obj){
    #if DEBUG == 1
        cout << "\t[DBG] " << "MyString::MyString(const MyString &obj)" << endl;
    #endif

    char *tmp;

    tmp = this->realloc(obj.length);
    strcpy(tmp, obj.str);

    this->set_values(tmp, obj.length);
}



/*Frees memory.*/
MyString::~MyString(){
    #if DEBUG == 1
        cout << "\t[DBG] " << "MyString::~MyString()" << endl;
        cout << "\t      " << "this->str " << (void *)this->str << endl;
    #endif

    delete [] this->str;
}


/*This function mus be called whenever necessary to change the values of member values
*/
void MyString::set_values(char *x, int y){
    #if DEBUG == 1
        cout << "\t[DBG] " << "MyString::set_values(char *x, int y)" << endl;
    #endif


    this->str = x;
    this->length = y;

    #if DEBUG == 1
        cout << "\t      " << "this->str " << (void *)this->str << endl;
    #endif
}



/*Allocate size+1(for nullbyte) bytes of memory.

Frees memory if neccessary.
*/
char *MyString::realloc(int size){
    #if DEBUG == 1
        cout << "\t[DBG] " << "MyString::realloc(int size)" << endl;
        cout << "\t      " << "this->str " << (void *)this->str << endl;
    #endif


    //delete [] this->str;

    return new char [size+1];
}



/*Initialize member-vaules with zeros.

Must be called in constructor.
*/
void MyString::init(){
    #if DEBUG == 1
        cout << "\t[DBG] " << "MyString::init()" << endl;
    #endif

    this->set_values((char *)0, 0);
}

Последний раз редактировалось Agmentium78; 18.03.2012 в 16:40.
Agmentium78 вне форума Ответить с цитированием
Старый 18.03.2012, 15:35   #4
S1av0k
Пользователь
 
Регистрация: 26.11.2009
Сообщений: 87
По умолчанию

Моё мнение - у тебя вообще ни один конструктор не работает так, как положено. А теперь скажи, пожалуйста, зачем тебе
Код:
init()
и
Код:
char *tmp
Помог - жми весы
S1av0k вне форума Ответить с цитированием
Старый 18.03.2012, 15:48   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

почему в realloc неверно записан вызов delete?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 18.03.2012, 16:34   #6
Agmentium78
 
Регистрация: 18.03.2012
Сообщений: 7
По умолчанию

Цитата:
Сообщение от S1av0k Посмотреть сообщение
Моё мнение - у тебя вообще ни один конструктор не работает так, как положено. А теперь скажи, пожалуйста, зачем тебе
Код:
init()
и
Код:
char *tmp
Можно поподробней что не так с конструкторами? Я видимо чего-то не понимаю.

init() должен обнулить переменные члены перед их использованием, в отдельную функцию вынес для наглядности.

char* tmp - ну можно и без него впринципе, поправлю.


Цитата:
почему в realloc неверно записан вызов delete?
Это я случайно изменил, нужно delete [] this->str я так понимаю, поправил.


Кстати! Если закоментировать этот оператор, программа не вылетает. Может быть я что-то не так сделал с конструктором копии и память освобождается дважды?

Спс всем кто отписал.
Agmentium78 вне форума Ответить с цитированием
Старый 18.03.2012, 16:39   #7
Agmentium78
 
Регистрация: 18.03.2012
Сообщений: 7
По умолчанию

Вот что я еще нашёл.

Такой вариант функции main() отрабатывает

Код:
    MyString mystr_first;

    cout << "MyString mystr_first" << endl;
    mystr_dbg(mystr_first);
    mystr_dbg(mystr_first);
    mystr_dbg(mystr_first);
    mystr_dbg(mystr_first);
    mystr_dbg(mystr_first);

    //if (false)
       //mystr_dbg(mystr_first);
А если раскомментировать условие, даже с учетом того, что функция вызвана не будет программа все-равно падает =\

Я похоже очень жестко накосячил, вот только неясно где.
Agmentium78 вне форума Ответить с цитированием
Старый 18.03.2012, 16:42   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

проверьте, точно ли вызываеться конструктор копии.(вставьте в него
Код:
std::cout<<"Copy constructor"<<std::endl;
)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 18.03.2012, 16:50   #9
Agmentium78
 
Регистрация: 18.03.2012
Сообщений: 7
По умолчанию

Вызывается.

Никто не пробовал компилировать? Может это только у меня такая проблема? Посмотрите кто может.

____________

Если посмотреть вывод с отладкой, то вот такая функция main()

Код:
    MyString mystr_first;

    cout << "MyString mystr_first" << endl;
    mystr_dbg(mystr_first);
отрабатывает так:
Код:
        [DBG] MyString::MyString()
        [DBG] MyString::init()
        [DBG] MyString::set_values(char *x, int y)
              this->str 0
        [DBG] MyString::realloc(int size)
              this->str 0
        [DBG] MyString::set_values(char *x, int y)
              this->str 0x7a1148
MyString mystr_first
        [DBG] MyString::MyString(const MyString &obj)
        [DBG] MyString::realloc(int size)
              this->str 0x28ff28
        [DBG] MyString::set_values(char *x, int y)
              this->str 0x7a11c0
        this->length == 0
        this->str == ''
        this->str 0x7a11c0

        [DBG] MyString::~MyString()
              this->str 0x7a11c0
        [DBG] MyString::~MyString()
              this->str 0x7a1148
Там виден вызов realloc(), в котором перед освобождением памяти this->str указывает на 0x28ff28, а это отличается от остальных адресов в куче. Может здесь что-то не так?
Agmentium78 вне форума Ответить с цитированием
Старый 18.03.2012, 17:51   #10
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Agmentium78

Все ошибки в программе связаны с незнанием базовых вещей C++ и неумелом обращении с динамическими данными.

повсеместно используется char* вместо const char* (хотя само по себе использование новичком указателей в C++, как правило, уже означает что код можно в помойку)

tmp = realloc(0);
tmp[0] = '\0';

выделяешь память размером в 0 байт и тут же пишешь в несуществующую область
отсутствует пере-определенный конструктор копирования, оператор присваивания, что является обязательным при наличии в классе raw указателей.

дальше смотреть не обязательно, и так все понятно...

ошибки такого рода возникают от незнания теории, поэтому лучший способ избежать их - усесться за учебники
Rififi вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
DBGrid конкретная ячейка Niklan БД в Delphi 6 24.01.2013 07:31
Nero - ошибка драйвера DMA. ошибка CRC NecRoMat Софт 5 09.05.2012 01:29
Ошибка run-time Error 1004 общая ошибка ODBC kaval88 Microsoft Office Excel 0 27.02.2011 20:20
Ошибка в коде, ошибка в css или это проблема с совместимостью с браузерами? ankris HTML и CSS 5 23.11.2010 16:58
Это ошибка Delphi или моя ошибка??? bloodeagle Общие вопросы Delphi 3 12.11.2009 15:26