Форум программистов, компьютерный форум CyberForum.ru

Компилятор оптимизировал мой код, и я не могу его отладить - C++

Восстановить пароль Регистрация
 
bychevoz
1 / 1 / 0
Регистрация: 16.11.2012
Сообщений: 27
22.12.2012, 04:43     Компилятор оптимизировал мой код, и я не могу его отладить #1
пишу лабу одногруппнице. задание: определить двунаправленный циклический список. элементы типа char*
реализовать функции:
1. проверка на пустоту
2. сколько элементов с одинаковыми соседями?
3. существует ли элемент равный следующему?
4. переставить элементы в обратном порядке между первым и последним вхождениями
5. вывод в файл.

для себя добавил функцию create и add
ООП не проходили. задание вообще странновато, мы прошли STL, мы не прошли язык Си, то есть никто не знает про strcmp() printf/scanf и т.д. ну это такое. всем известно что 70% времени находимся в универе и 70% инфы находим сами. неважно

на одном дыхании написал я вот такой вот говнокод:
list.h: (не парился с ifdef ifndef так как опять же раздельную компиляцию нам объяснили абыкак, а подруга объяснить не сможет)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
struct Elem 
{
    Elem *prev, *next;
    char *data;
};
 
typedef Elem* List;
 
List create(); //создать список
void add(List l, char* _data); //добавить елем
 
bool is_empty(List l); //пустой?
int  how_many_with_equal_neighbours(List l); //сколько эл-тов с одинаковыми соседями?
bool equal_to_next_exists(List l); //существует ли элемент равный следующему?
void inverse_between(List l, char* el); //переставить в обратном порядке между первым и последним вхождениями
void write(List l, std::ostream& out=std::cout); //написать в поток (cout по умолчанию, но можно использовать файловые потоки)
code.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "list.h"
 
 
List create() //создать список
{
    List l=new Elem; //выделяем память для списка
    l->data=""; //делаем пустую строку
    l->next=0; //указатель на следующий нулевой
    l->prev=0; //указатель на предыдущий - нулевой
    return l;
    /*сформировали заглавное звено списка*/
}
 
void add(List l, char* _data) //добавить елем
{
    if (!l->next) //если список пуст
        l->next->next=l->next->prev=l->next=new Elem; //создаем элемент и сразу зацикливаем его сам на себя (присваивание справа на лево)
    else
    {
        Elem* old_tail=l->next->prev; //сохраняем старый
        l->next->prev=l->next->prev->next=new Elem; //выделяем память (это будет новый хвост),хвост привязываем к последнему элементу, а потом к первому
        old_tail->next->prev=old_tail; //привязываем старый хвост к новому
        l->next->prev->next=l; //привязываем голову к хвосту
    }
    l->next->prev->data=_data; //заполняем хвост (выполняется в любом случае)
}
 
bool is_empty(List l) //пустой?
{
    return !l->next; //ну тут ясно. если указатель на следующий нулевой, вернем правду иначе ложь
}
 
int  how_many_with_equal_neighbours(List l) //сколько эл-тов с одинаковыми соседями?
{
    if (!l->next) return 0;
    Elem* tail=l->next->prev;//сохранили хвост
    int i=0;
    while ((l!=tail) && ( (l=l->next) || (i+=(strcmp(l->next->data, l->prev->data)?0:1)) ) );
    /* эквивалентно:
    while (l!=tail) 
    {
        if (!strcmp(l->next->data, l->prev->data) i++;
        l=l->next;
    }*/
    return i;
}
 
bool equal_to_next_exists(List l) //существует ли элемент равный следующему?
{
    if (!l->next) return false;
    Elem* tail=l->next->prev;
    while ((l=l->next) && strcmp(l->data,l->next->data) && l!=tail);
    /*эквивалентно:
    while (l!=tail)
    {
        l=l->next;
        if (!strcmp(l->data,l->next->data)) break;
    }*/
    return l!=tail || strcmp(l->data,l->next->data); //если не дошли до конца, или же если дошли, но последний равен первому
}
 
void inverse_between(List l, char* el) //переставить в обратном порядке между первым и последним вхождениями
{
    if (l->next==l->next->prev) return; //если список зациклен сам на себе, то там один элемент. если список пуст то оба указателя равны нулю
    Elem *first=0, *last=0, *tail=l->next->prev;
    while (l!=tail) 
    //нахождение первого и последнего вхождения:
    {
        l=l->next; //переходим к след. элементу
        if (!strcmp(l->data,el)) //если нашли строку
            if (!first) first=l; //если первое вхождение не найдено, то первое вхождение = этому звену
            else last=l; //иначе последнее вхождение = этому звену
    }
    if (!last) return; //если нету последнего вхождения, то елемент встречается один раз, так что выходим
    char* temp;
    while (first!=last && first->next!=last) //1е условие - если у нас нечетное кол-во эл-тов между first и last, 2е условие - если четное.
    {
        //передвигаем указатели навстречу друг другу
        first=first->next;
        last=last->prev;
        //меняем элементы местами
        temp=first->data;
        first->data=last->data;
        last->data=temp;
    }
}
 
void write(List l, std::ostream& out) //написать в поток (cout по умолчанию, но можно использовать файловые потоки)
{
    Elem* tail=l->next->prev;
    while (l!=tail) 
    {
        l=l->next;
        out<<l->data<<'\n';
    }
}
ну и наконец: main.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
#include "list.h"
 
void main()
{
    printf("Fill the list with 10 elements:\n");
    List list=create();
    add(list,"mm");
    for (int i=1; i<=10; i++)
    {
        char* el=new char[255]; 
        //если объявим снаружи цикла, адрес строки будет всегда один и тот же, и все элементы списка будут одинаковыми
        scanf("%s",el); //читаем с консоли 
        add(list,el); //добавляем в список
    }
    printf("\nYour list:\n");
    write(list); //выводим список в консоль
    if (!is_empty(list)) 
    {
        printf("Count of elements with equal neighbours: %d\n", how_many_with_equal_neighbours(list));
        printf("Element that equals to his right neighbour "+(equal_to_next_exists(list))?"exists":"does not exist\n");
        printf("Input string: ");
        char* str=new char[255];
        scanf("%s",str);
        inverse_between(list,str);
        printf("\n\nIf at least two \"%s\" are in list, the elements between first and last \"%s\" will be inverted",str,str);
        write(list);
    }
    else printf("The list is empty");
    system("pause");
}
теперь суть проблем:
проблем всего три: две мелкие и одна - вообще огонь
мелкая: некорректно работает how_many_with_equal_neighbours(list)
я как нормальный белый человек поставил точку останова, и давай f10 жать.
и тут меня начал есть факт, что нету автоматической слежки за переменными (как ее добавить - первая мелкая проблема)
некоторые переменные вообще нельзя отследить: в функции main не могу проследить за list, в функции how_many_with_equal_neighbours(list) не могу проследить за счетчиком i (вторая мелка проблема)

ну я себе и думаю: чтото не так с add(). давайте ка глянем в add
остановил отладку, поставил останов в add() и компилятор в него не зашел. я поставил останов перед вызовом add, жму f11. та же фигня, пропускает. а потом вижу, всплывает хинт: что-то по типу не могу зайти в функцию, так как я оптимизировал её и кода как такового нету, используйте директиву нескажу какую.
в общем это и есть та огонь-проблема. как мне отдебажить эту функцию, как убрать или поставить директиву, чтобы этот компилятор не оптимизировал мой восхитительнейший код?

я со своим кодом разобраться вполне могу, хотя советы не помешают, но все же главное - как решить те три проблемы которые я описал?

и да, если не лень, гляньте вообще весь код, не только проблемные функции. как можно его еще сократить (я только начал страдать этой фигней, собственно почему я люблю Си - за короткие и непонятные конструкции которые можно объяснять преподам и выглядеть умным)

Заранее спасибо

Добавлено через 6 минут
блин, перечитываю код, уже вижу ошибку в add()
code.cpp строка 23
вместо
l->next->prev->next=l; //привязываем голову к хвосту
надо
l->next->prev->next=l->next; //привязываем голову к хвосту

Добавлено через 19 минут
и еще одна ошибка, строка 59
вместо
return l!=tail || strcmp(l->data,l->next->data);
надо
return l!=tail || !strcmp(l->data,l->next->data);

все время забываю что strcmp() действует наоборот

Добавлено через 32 минуты
в общем я сделал эту функцию так: чуть чуть удлинил. видимо что-то неверно сократил, интересно что. и как убрать эту оптимизацию, на всякий случай расскажите все же. и переменные как наблюдать

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int  how_many_with_equal_neighbours(List l) //сколько эл-тов с одинаковыми соседями?
{
    if (!l->next) return 0;
    Elem* tail=l->next->prev;//сохранили хвост
    int i=0;
    do l=l->next; while ((l!=tail) && ( /*(l=l->next) ||*/ (i+=(strcmp(l->next->data, l->prev->data)?0:1)) ) );
    //эквивалентно:
    /*while (l!=tail) 
    {
        l=l->next;
        if (!strcmp(l->next->data, l->prev->data)) i++;
    }*/
    return i;
}
Добавлено через 1 минуту
как я выяснил в строке 6 никак не хотела выполняться l=l->next
удалось проследить за переменной l , но вот же зараза, цикл выполнялся ровно столько раз сколько в списке элементов. ужас какой-то, это я дурак или компилятор?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.12.2012, 04:43     Компилятор оптимизировал мой код, и я не могу его отладить
Посмотрите здесь:

Мой компилятор не принимает "getline" и не хочет массив объявлять peson p[a] C++
Подправьте мой код) C++
пожалуйста отладить код нахождения минимального и максимального элемента в линейном массиве из 15 элементов C++
Подскажите как отладить код (связанные списки) C++
Дано шестнадцатеричное число. Написать и отладить программу для вывода на экран его двоичного представления C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nixy
ComfyMobile
 Аватар для Nixy
399 / 280 / 8
Регистрация: 24.07.2012
Сообщений: 916
22.12.2012, 10:31     Компилятор оптимизировал мой код, и я не могу его отладить #2
Цитата Сообщение от bychevoz Посмотреть сообщение
что нету автоматической слежки за переменными
в какой среде разработке работаете? я подозреваю что Visual Studio, я в ней не работаю но мне кажется что у майкрософта хватало ума чтоб гдето поместить окошко с локальными переменными, если не в ней, или не хватило( что сомнительно) есть такая штука называется watch, надо полазить на панели инструментов и где-то найтиЮ либо addwatch либо watchlist
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,040
22.12.2012, 10:59     Компилятор оптимизировал мой код, и я не могу его отладить #3
Цитата Сообщение от Nixy Посмотреть сообщение
в какой среде разработке работаете? я подозреваю что Visual Studio, я в ней не работаю но мне кажется что у майкрософта хватало ума чтоб гдето
дак у у неё ума то хватает
не хватает у пользователей, которые пытаются в Relise отлаживать (а там уже оптимизатор все перекрутил) вместо Debug

Добавлено через 1 минуту
Цитата Сообщение от bychevoz Посмотреть сообщение
do l=l->next; while ((l!=tail) && ( /*(l=l->next) ||*/ (i+=(strcmp(l->next->data, l->prev->data)?0:1)) ) );
* * //эквивалентно:
сам себе злобный буратино
интересно что можно отладить в такой строчке
Nixy
ComfyMobile
 Аватар для Nixy
399 / 280 / 8
Регистрация: 24.07.2012
Сообщений: 916
22.12.2012, 11:14     Компилятор оптимизировал мой код, и я не могу его отладить #4
C++
1
2
3
4
5
do {
     l=l->next;
     i+=(strcmp(l->next->data , l->prev->data)?0:1);
    }
    while ((l!=tail));
с такой конструкцией все работает, единственое хочу уточнить, голова не должна быть к хвосту привязана быть?
ValeryS
Модератор
6374 / 4840 / 441
Регистрация: 14.02.2011
Сообщений: 16,040
22.12.2012, 11:48     Компилятор оптимизировал мой код, и я не могу его отладить #5
Цитата Сообщение от Nixy Посмотреть сообщение
с такой конструкцией все работает,
так работать то работает
а если нет? как отлаживать?
чему равна l->next->data l->prev->data
что вернет strcmp ?
для отладки лучше разбить на три строчки и ввести временные переменные
Nixy
ComfyMobile
 Аватар для Nixy
399 / 280 / 8
Регистрация: 24.07.2012
Сообщений: 916
22.12.2012, 12:15     Компилятор оптимизировал мой код, и я не могу его отладить #6
не ну для отладки то да каждое действие по полкам, но потом то собрать надо, проблема то не в отладке была вроде как), а в том что внутри условия оператор
C++
1
i+=(strcmp(l->next->data , l->prev->data)?0:1);
не работал

Добавлено через 2 минуты
о увидел про голову и хвост
l->next->prev->next=l->next; //привязываем голову к хвосту
Avazart
 Аватар для Avazart
6896 / 5136 / 251
Регистрация: 10.12.2010
Сообщений: 22,568
Записей в блоге: 17
22.12.2012, 16:26     Компилятор оптимизировал мой код, и я не могу его отладить #7
Цитата Сообщение от bychevoz Посмотреть сообщение
list.h: (не парился с ifdef ifndef так как опять же раздельную компиляцию нам объяснили абыкак, а подруга объяснить не сможет)
Лучше использовать assert - ты, ну или накрайняк самописные ф-ции, но и с макросами ничего сложного нет.

Ну это для отладки, а вообще обычно еще исключения возбуждают при ошибках

Добавлено через 5 минут
Цитата Сообщение от bychevoz Посмотреть сообщение
C++
1
2
3
4
bool is_empty(List l) //пустой? 
{ 
  return !l->next; //ну тут ясно. если указатель на следующий нулевой, вернем правду иначе ложь
}
Равноценно

C++
1
2
3
4
bool is_empty(List l) //пустой? 
{ 
  return (l->next == NULL);
}
Добавлено через 36 минут
Цитата Сообщение от bychevoz Посмотреть сообщение
list.h: (не парился с ifdef ifndef так как опять же раздельную компиляцию нам объяснили абыкак, а подруга объяснить не сможет)
М.. прдон не понял я наверное суть вопроса ... наверное речь про "стражи включения",
а не про отладку http://ru.wikipedia.org/wiki/Include_guard
bychevoz
1 / 1 / 0
Регистрация: 16.11.2012
Сообщений: 27
23.12.2012, 02:37  [ТС]     Компилятор оптимизировал мой код, и я не могу его отладить #8
Цитата Сообщение от bychevoz Посмотреть сообщение
как я выяснил в строке 6 никак не хотела выполняться l=l->next
удалось проследить за переменной l , но вот же зараза, цикл выполнялся ровно столько раз сколько в списке элементов. ужас какой-то, это я дурак или компилятор?
Цитата Сообщение от bychevoz Посмотреть сообщение
некоторые переменные вообще нельзя отследить: в функции main не могу проследить за list, в функции how_many_with_equal_neighbours(list) не могу проследить за счетчиком i (вторая мелка проблема)
а с этим как быть?

и я знаю что такое watch можете просто подсказать в какой менюшке сделать его автоматическим
Nixy
ComfyMobile
 Аватар для Nixy
399 / 280 / 8
Регистрация: 24.07.2012
Сообщений: 916
23.12.2012, 10:25     Компилятор оптимизировал мой код, и я не могу его отладить #9
ну погуглите что такое watch я не знаю где вы работаете, в какой среде,и поэтому врятли смогу подсказать, а по сути программы она работает если заменить тем что мы написали вашу конструкцию, все делает
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.12.2012, 07:45     Компилятор оптимизировал мой код, и я не могу его отладить
Еще ссылки по теме:

Не могу отладить программу, не понимаю, что нужно сделать C++
Рекурсия, нужно отладить код C++
Массивы - отладить код; В переменную Summa никакие значения не записываются C++

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

Или воспользуйтесь поиском по форуму:
bychevoz
1 / 1 / 0
Регистрация: 16.11.2012
Сообщений: 27
24.12.2012, 07:45  [ТС]     Компилятор оптимизировал мой код, и я не могу его отладить #10
да , я понял что основная проблема что я пытался отлаживать release))
Yandex
Объявления
24.12.2012, 07:45     Компилятор оптимизировал мой код, и я не могу его отладить
Ответ Создать тему
Опции темы

Текущее время: 21:47. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru