• 🔥 Бесплатный курс от Академии Кодебай: «Анализ защищенности веб-приложений»

    🛡 Научитесь находить и использовать уязвимости веб-приложений.
    🧠 Изучите SQLi, XSS, CSRF, IDOR и другие типовые атаки на практике.
    🧪 Погрузитесь в реальные лаборатории и взломайте свой первый сайт!
    🚀 Подходит новичкам — никаких сложных предварительных знаний не требуется.

    Доступ открыт прямо сейчас Записаться бесплатно

Помогите исправить код задачи...

  • Автор темы Автор темы xparen
  • Дата начала Дата начала
X

xparen

Помогите найти ошибку в коде... Программа написана в оконном режиме.. при нажатии клавиши Просмотр... программа зацикливаеться и выводит без конца одно и то же число... Ниже код программы... Также прикрепляю всю программу целиком.

C++:
//---------------------------------------------------------------------------
struct Stack {
int info;
Stack * next;
} *begin, *t;
//---------------------------------------------------------------------------
Stack* InStack(Stack*, int);
void View(Stack*);
void Del_All(Stack **);
//--------------------------------- Создать ---------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
//------проверка перед созданием----
{
int i, in, n = StrToInt(Edit1->Text);
if(begin != NULL){
ShowMessage("Освободите память!");
return;
}
//----------------------------------
for(i = 1; i <= n; i++){
in = random(20);
begin = InStack(begin, in);
}
Memo1->Lines->Add("Создано элементов " + IntToStr(n));
}
//---------------------------- Добавить -------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
int i, in, n = StrToInt(Edit2->Text);
for(i = 1; i <= n; i++){
in = random(20);
begin = InStack(begin, in);
}
Memo1->Lines->Add("Добавлено элементов " + IntToStr(n));
}
//-------------------------------- Очистить ---------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)
{
if (begin != NULL) Del_All(&begin);
ShowMessage("Память освобождена!");
}
//------------------------------------ Выход --------------------------------

void __fastcall TForm1::Button5Click(TObject *Sender)
{
if(begin != NULL) Del_All(&begin);
Close();
}
//------------------------------- Просмотр ----------------------------------


void __fastcall TForm1::Button6Click(TObject *Sender)
{
if(!begin){
ShowMessage("Стек Пуст!");
return;
}
Memo1->Lines->Add("--- Элементы ---");
View(begin);
}
//----------------------------- Ф-ия добавки --------------------------------
Stack* InStack(Stack *p, int in) {
Stack *t = new Stack;
t -> info = in;
t -> next = p;
return t;
}
//----------------------------- ф-ия просмотра ------------------------------
void View(Stack *p) {
Stack *t = p;
while( t != NULL) {
Form1->Memo1->Lines->Add("  " + IntToStr( t->info));
}
}
//---------------------------- ф-ия освобождения памяти ---------------------
void Del_All(Stack **p) {
while(*p != NULL) {
t = *p;
*p = (*p) -> next;
delete t;
}
}
 

Вложения

  • 2.2.zip
    2.2.zip
    4,4 КБ · Просмотры: 160
А самому поискать, лень что ли? Ты бы хоть место нашёл, где программа в цикл падает, а потом бы анализировал почему так.

C++:
std::cout << "line: "<< __LINE__ << std::endl;
Вставь в циклы, которые больше всего подозреваешь, и смотри где программа циклится.
 
А самому поискать, лень что ли? Ты бы хоть место нашёл, где программа в цикл падает, а потом бы анализировал почему так.
Не хочу показаться грубым, но я пишу тему в разделе, специально созданном для таких "ляпов" и ошибок. Если бы я сам мог найти эту ошибку, я бы давно это сделал и не писал, откровенно говоря, тупых сообщений с вашей стороны.
Надеюсь на дальнейшее взаимопонимание и поддержку.
 
Чего так переживать? Поверьте мне мало кто захочет искать в этом коде ошибку. А совет я вам дал дельный, не знаю почему вы не хотите им воспользоваться, так вы её самостоятельно проще всего и найдёте. Программист должен учится не только непосредственно программированию, но и поиску ошибок в коде.
 
Все нашел ошибку....
В функции просмотра после вывода в Memo1 не хватает перемещения текущего элемента на следующий, т.е.
t=t->next;
 
С программой разобрался... Но снова
C++:
void del_chet(Stack **p) {
while(*p != NULL) {
t = *p;
*p = (*p) -> next;
if((t->info)%2==0)
delete t;
}
}

Вроде, должна работать.... Но не работает=)) (должна удалять из стека четные элементы)

Что здесь не так?!
 
Сложно, конечно, разобраться в этом кусочке. Рискну предположить, что здесь происходит смещение элементов, а потом удаление с проверкой условия. Только тогда получается что второй элемент запишется на место первого. Почему перезапись происходит даже тогда, когда элементы не удаляются?
 
эта функция работает, но не так как надо... совсем...
после выполнения её удаляеться весь стек целиком, а не его четные элементы.... вопрос почему?!
 
Показывай исправленный код целиком.

Вылаживаю весь код целиком (оконное приложение). Файлы программы ниже. Привожу здесь текст того, что у меня получилось. Суть: ввод(вывод) данных в(из) стека (случайные числа), удаление из стека четных чисел (вот именно эта ф-ия не работает правильно, а удаляет стек целиком).
C++:
struct Stack {
int info;
Stack * next;
} *begin, *t;
//---------------------------------------------------------------------------
Stack* InStack(Stack*, int);
void View(Stack*);
void Del_All(Stack **);
void Resh(Stack **);
//--------------------------------- Создать ---------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
//------проверка перед созданием----
{
int i, in, znak, n = StrToInt(Edit1->Text);
if(begin != NULL){
ShowMessage(" Освободите память ");
return;
}
//----------------------------------
for(i = 1; i <= n; i++){
in = random(20);
znak = random(2);
if(znak < 1)
in=in*(-1);
begin = InStack(begin, in);
}
Memo1->Lines->Add("Создано элементов " + IntToStr(n));
}
//---------------------------- Добавить -------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
int i, in, znak, n = StrToInt(Edit2->Text);
for(i = 1; i <= n; i++){
in = random(100);
znak = random(2);
if(znak < 1)
in=in*(-1);
begin = InStack(begin, in);
}
Memo1->Lines->Add("Добавлено элементов " + IntToStr(n));
}
//-------------------------------- Очистить ---------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)
{
if (begin != NULL) Del_All(&begin);
ShowMessage(" Память освобождена ");
}
//------------------------------------ Выход --------------------------------

void __fastcall TForm1::Button5Click(TObject *Sender)
{
if(begin != NULL) Del_All(&begin);
Close();
}
//------------------------------- Просмотр ----------------------------------


void __fastcall TForm1::Button6Click(TObject *Sender)
{
if(!begin){
ShowMessage(" Стек Пуст ");
return;
}
Memo1->Lines->Add("--- Элементы ---");
View(begin);
}
//----------------------------- Ф-ия добавки --------------------------------
Stack* InStack(Stack *p, int in) {
Stack *t = new Stack;
t -> info = in;
t -> next = p;
return t;
}
//----------------------------- ф-ия просмотра ------------------------------
void View(Stack *p) {
Stack *t = p;
while( t != NULL) {
Form1->Memo1->Lines->Add("  " + IntToStr( t->info));
t=t->next; 
}
}
//---------------------------- ф-ия освобождения памяти ---------------------
void Del_All(Stack **p) {
while(*p != NULL) {
t = *p;
*p = (*p) -> next;
delete t;
}
}
//-------------------------------------------------------------------------------
//--------------------------------- Удаление ---------------------------------
//-------------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
if(!begin){
ShowMessage(" Стек Пуст ");
return;
}
Memo1->Lines->Add("--- Решение ---");
Resh(&begin);
View(begin);
}
//----------------------------------- ф-ия удаления четных чисел ---------
void Resh(Stack **p) {
while(*p != NULL) {
t = *p;
*p = (*p) -> next;
if((t->info)%2==0)
delete t;
}
}
 

Вложения

  • 2.2.zip
    2.2.zip
    784,4 КБ · Просмотры: 168
Слишком много чего исправлять. Смотри мой пример и делай по аналогии:
C++:
#include <iostream.h>

struct xlist {
int		value;
xlist *	next;
};

struct xlist *	first	= NULL;
struct xlist *	last	= NULL;

void add( int val )
{
struct xlist * p = new xlist;
p->value = val;
p->next = NULL;
if ( !last ) {
first = p;
last = p;
} else {
last->next = p;
last = p;
}
}

void del_even()
{
struct xlist * a = first;
while ( a && !(a->value & 1) ) a = a->next;
first = a;

while ( a && a->next ) {
if ( !(a->next->value & 1) ) {
a->next = a->next->next;
} else {
a = a->next;
}
}
}

void print()
{
struct xlist * p = first;
while ( p ) {
cout << p->value << endl;
p = p->next;
}
}

int main()
{
for ( int i = 0; i < 10; i++ ) {
add( i );
}
del_even();
print();
return 0;
}
 
Спасибо, круто работает.... быстро, и четко, и без лишнего.... Только плз можешь еще объяснить как работает удаление?! а то что-то капался в функции удаления... но не сообразил как это происходит.... С МЕНЯ ПЕЧЕНЬКА=) ввиде + в репутацию=)
C++:
void del_even()
{
struct xlist * a = first;
while ( a && !(a->value & 1) )
a = a->next;
first = a;

while ( a && a->next ) {
if ( !(a->next->value & 1) ) {
a->next = a->next->next;
} else {
a = a->next;
}
}
}
 
Тут происходит перебор элементов с самого начала до тех пор пока не встретится первый нечетный, т.е. все четные с самого начала пропускаются и в конце указатель first указывает на первый нечетный элемент:
C++:
	struct xlist * a = first;
while ( a && !(a->value & 1) ) a = a->next;
first = a;

Тут, начиная с нечетного элемента перебираются все остальные и из них так же удаляются все четные:
C++:
	while ( a && a->next ) {
if ( !(a->next->value & 1) ) { // если a->next четный ...
a->next = a->next->next; // пропускаем
} else {
a = a->next; // не пропускаем
}
}

P.S.: единственное о чем я забыл, так это об освобождении памяти удаляемых элементов)
 
Так будет правильней:
C++:
void del_even()
{
struct xlist * a = first;
struct xlist * b;
while ( a && !(a->value % 2) ) {
b = a;
a = a->next;
delete b;
}
first = a;

while ( a && a->next ) {
if ( a->next->value % 2 ) {
// odd
a = a->next;
} else {
// even
b = a->next;
a->next = a->next->next;
delete b;
}
}
}
 
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab