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

  • 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

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

  • Автор темы 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
    4,4 КБ · Просмотры: 115
I

ierofant

А самому поискать, лень что ли? Ты бы хоть место нашёл, где программа в цикл падает, а потом бы анализировал почему так.

C++:
std::cout << "line: "<< __LINE__ << std::endl;
Вставь в циклы, которые больше всего подозреваешь, и смотри где программа циклится.
 
X

xparen

А самому поискать, лень что ли? Ты бы хоть место нашёл, где программа в цикл падает, а потом бы анализировал почему так.
Не хочу показаться грубым, но я пишу тему в разделе, специально созданном для таких "ляпов" и ошибок. Если бы я сам мог найти эту ошибку, я бы давно это сделал и не писал, откровенно говоря, тупых сообщений с вашей стороны.
Надеюсь на дальнейшее взаимопонимание и поддержку.
 
I

ierofant

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

xparen

Все нашел ошибку....
В функции просмотра после вывода в Memo1 не хватает перемещения текущего элемента на следующий, т.е.
t=t->next;
 
X

xparen

С программой разобрался... Но снова
C++:
void del_chet(Stack **p) {
while(*p != NULL) {
t = *p;
*p = (*p) -> next;
if((t->info)%2==0)
delete t;
}
}

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

Что здесь не так?!
 
I

ierofant

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

xparen

эта функция работает, но не так как надо... совсем...
после выполнения её удаляеться весь стек целиком, а не его четные элементы.... вопрос почему?!
 
X

xparen

Показывай исправленный код целиком.

Вылаживаю весь код целиком (оконное приложение). Файлы программы ниже. Привожу здесь текст того, что у меня получилось. Суть: ввод(вывод) данных в(из) стека (случайные числа), удаление из стека четных чисел (вот именно эта ф-ия не работает правильно, а удаляет стек целиком).
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
    784,4 КБ · Просмотры: 116
L

lazybiz

Слишком много чего исправлять. Смотри мой пример и делай по аналогии:
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;
}
 
X

xparen

Спасибо, круто работает.... быстро, и четко, и без лишнего.... Только плз можешь еще объяснить как работает удаление?! а то что-то капался в функции удаления... но не сообразил как это происходит.... С МЕНЯ ПЕЧЕНЬКА=) ввиде + в репутацию=)
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;
}
}
}
 
L

lazybiz

Тут происходит перебор элементов с самого начала до тех пор пока не встретится первый нечетный, т.е. все четные с самого начала пропускаются и в конце указатель 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.: единственное о чем я забыл, так это об освобождении памяти удаляемых элементов)
 
L

lazybiz

Так будет правильней:
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;
}
}
}
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!