Глюк с С++

Тема в разделе "WASM.BEGINNERS", создана пользователем Prohvost, 23 ноя 2008.

  1. Prohvost

    Prohvost New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    107
    Добрый день.
    Делаю тестовое задание по С++, возник глюк, объяснения которому не могу найти. Задание (вкратце) такое:
    Я реализовал. вот так:
    derevo.h:
    Код (Text):
    1. #define ADDROST 1
    2. #define ADDVOZRAST 1
    3.  
    4. #define MAXX 1000
    5. #define MAXY 1000
    6.  
    7.  
    8.  
    9. class derevo
    10. {
    11.     char name[256];
    12.     int rost;
    13.     int vozrast;
    14. public:
    15.     int GetRost();
    16.     int GetVozrast ();
    17.  
    18.     int GetName(char *Name);
    19.     int SetName(char *Name);
    20.     void Rosti();
    21.     void Copy(derevo newDer);
    22.     int Srav(derevo SravDer);
    23.     derevo();
    24.     virtual ~derevo();
    25.  
    26. };
    27.  
    28. struct derlist
    29. {
    30.     derevo * der;
    31.     struct derlist * list;
    32. };
    33.  
    34. class les
    35. {
    36.     int x;
    37.     int y;
    38.     int count;// счетчик деревьев
    39.     derevo ** doska;
    40. public:
    41.     int AddDer();
    42.     bool DelDer(int x, int y);
    43.     int GetCount();
    44.  
    45.     bool  GetSortList(derevo **list);
    46.     int GetCountCrug(int x, int y, int radius);
    47.     derevo* FindDer(char *FindName);
    48.  
    49.     les();
    50.     virtual ~les();
    51. };
    derevo.cpp:
    Код (Text):
    1. #include <stdlib.h>
    2. #include <stdio.h>
    3. #include <time.h>
    4. #include <string.h>
    5. #include <math.h>
    6.  
    7. #include "derevo.h"
    8. derevo::derevo()
    9. {
    10.     srand( (unsigned)time( NULL ) );
    11.  
    12.     rost = rand()*50/RAND_MAX ;
    13.     vozrast = rost*7 ;
    14.     SetName("Elka");
    15.    
    16. }
    17. derevo::~derevo()
    18. {
    19. }
    20.  
    21. int derevo::GetRost()
    22. {
    23.     return rost;
    24. }
    25. int derevo::GetVozrast ()
    26. {
    27.     return vozrast;
    28. }
    29.  
    30. int derevo::GetName(char *Name)
    31. {
    32.     return (int)strcpy(Name, name);
    33. }
    34. int derevo::SetName(char *Name)
    35. {
    36.     return (int)strcpy(name,Name);
    37. }
    38. void derevo::Rosti()
    39. {
    40.     rost+=ADDROST;
    41.     vozrast+=ADDVOZRAST;
    42. }
    43. void derevo::Copy(derevo newDer)
    44. {
    45.     newDer.SetName(name);
    46.     newDer.rost = rost;
    47.     newDer.vozrast = vozrast;
    48.  
    49. }
    50. int derevo::Srav(derevo SravDer)
    51. {
    52.     if(SravDer.GetRost()<rost)
    53.     {
    54.         return -1;
    55.     }
    56.     else
    57.     {
    58.         if(SravDer.GetRost()==rost)
    59.         {
    60.             return 0;
    61.         }
    62.         return 1;
    63.     }
    64.  
    65. }
    66.  
    67.  
    68. les::les()
    69. {
    70.     x = MAXX;
    71.     y = MAXY;
    72.     doska = (derevo**)calloc(x*y, sizeof(derevo*));
    73.     count = 0;
    74.  
    75. }
    76.  
    77. les::~les()
    78. {
    79.     if (doska)
    80.     {
    81.         free(doska);
    82.     }
    83.  
    84. }
    85. bool les::DelDer(int x, int y)
    86. {
    87.     if(doska[x,y]!=0)
    88.     {
    89.         delete (derevo*)doska[x,y];
    90.         doska[x,y]=0;
    91.         return 1;
    92.     }
    93.     else
    94.     {
    95.         return 0;
    96.     }
    97.  
    98. }
    99. int les::AddDer()
    100. {
    101.     int x;
    102.     int y;
    103.     derevo* Der;
    104.     Der = new(derevo);
    105.     srand( (unsigned)time( NULL ) );
    106.     x =  rand()*MAXX/RAND_MAX ;
    107.     y =  rand()*MAXY/RAND_MAX ;
    108.  
    109.  
    110.  
    111.     if(doska[x,y]!=0)
    112.     {
    113.         AddDer();
    114.     }
    115.     else
    116.     {
    117.         doska[x,y]=Der;
    118.         count++;
    119.     }
    120.  
    121. return count;
    122. }
    123.  
    124. int les::GetCount()
    125. {
    126.     return count;
    127. }
    128. int les::GetCountCrug(int x, int y, int radius)
    129. {
    130.     int i;
    131.     int j;
    132.     int countKrug = 0;
    133.     for (i=x-radius-1;i<x+radius+1;i++)
    134.     {
    135.         for(j=y-radius-1;j<y+radius+1;j++)
    136.         {
    137.             if((doska[i,j]!=0)&&(radius>sqrt((x-i)*(x-i)+(y-j)*(y-j))))
    138.             {
    139.                 countKrug++;
    140.             }
    141.         }
    142.     }
    143.     return countKrug;
    144. }
    Вот. Вроде все компилируется без проблем, но при попытке потестировать вот таким кодом:
    Код (Text):
    1.     int chislo;
    2.     les lesss;
    3. //  lesss = new(les);
    4.     lesss.AddDer();
    5.     lesss.AddDer();
    6.     lesss.AddDer();
    7.     lesss.AddDer();
    8.     chislo = lesss.GetCount();
    выскакиевает ошибка 0xc0000005 Access violation, где то в AddDer
    Если проходить каждую строку медлено в отладчике, то все отрабатывает верно и без глюков, а если поставить бряк на последний AddDer, то выскакивает вот эта ошибка. Что за фигня такая может быть???
     
  2. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Код (Text):
    1. int les::AddDer()
    2. {
    3.       //бред поскипан
    4.  
    5.     if(doska[x,y]!=0)
    6.     {
    7.         AddDer();
    8.     }
    9.  
    10.       //бред поскипан
    11.  
    12. return count;
    13. }
    Скомпилировал, прогнал.
    В указанном месте - бесконечная рекурсия. Почему - разбирайся сам.
    Hint: рекурсия - это очень, очень плохо :) Ее всегда можно и нужно избегать.
     
  3. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Prohvost
    а не проще ли задание в тег "цитатко" обернуть ?
     
  4. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Рекурсия - это очень и очень удобный механимз. Но пользоваться им надо уметь !
     
  5. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    EvilsInterrupt
    в 99% случаев итерации предпочительней рекурсии в плане скорости и памяти.

    p.s. 1% исключений бывают, например сортировка Хоара
    p.s. оптимизированная хвостовая рекурсия не в счет, конечно
     
  6. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    Prohvost
    полезный совет: в рамках одной программы используй один способ работы с динамической памяти. Смешивать стиль С (malloc/free) и C++ (new/delete) очень плохая идея, т.к. можешь запутаться и, к примеру, попытаться освободить память, выделенную malloc'ом через delete, это может плохо кончится.
     
  7. Prohvost

    Prohvost New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    107
    Это да. Я просто торопился, хотелось написать все за несколько часов, но потом начал путаться. Зря торопился.
     
  8. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    Prohvost
    doska[x,y] делает не то что ты думаешь
     
  9. Prohvost

    Prohvost New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    107
    Уже понял. Хех, с наскока одолеть не удалось, буду на работе переписывать в свободные минуты все заново.
     
  10. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    meduza
    Вообще-то malloc выделяет память в стеке, а new в Heap, конечно это скорее всего компиляторозависимо, но имхо маленькие и совсем временные блоки лучше malloc, а более менее долгоиграющие new.
     
  11. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Это на башорг, однозначно.
     
  12. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Господа, я понимаю, что это форум изначально ассемблеро-ориентированный... Но прежде чем нести подобный бред, хотя бы загляните в стандарт С++. А то ведь молодежь читает это и верит! А потом появляются посты типа "а мне на одном форуме крутые спецы сказали, что типизация в С++ - это для того, чтобы память экономить, а вы тут, лохи, и не знаете!" :)
     
  13. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Кроме всего этого - однажды родившись дерево не может менять название - логическая, значить, проблемка.