Помогите найти ошибку

  • Автор темы 9a9z9a
  • Дата начала
9

9a9z9a

Гость
#1
Задача состоит в нахождении количества чисел-палиндромов
Вот мой код, он запускается, но нечего не показывает :)

C++:
#include <iostream>
using namespace std;
bool for_pal(int arr[], int sz) // функция для проверки является ли число палиндромом
{
int f;
for(f = 0; f < (sz / 2); f++) 
{
if(arr[f] == arr[sz - 1 - f])continue;
return false;
}
return true;
}
void main()
{
setlocale(LC_ALL, "Rus");
int *arr, kol_vo = 0, sz, g = 0;
int i,j;
int matrix[2][2] = {{777, 404}, {1991, -2091}};
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++) 
{
sz = 0; //начальный размер динамического массива(а так вообще можно? :ya_lamo: )
//пробывал с 1 , та же лажа
arr = new int[sz]; // создаем динамический массив, в который заносим цифры элемента matrix[i][j]
if(!arr) {cout<<"LOL!\n"; return;}
while(matrix[i][j]) //заносит цифры в динамический массив
{
sz++;
arr[g++] = (matrix[i][j] % 10); 
matrix[i][j] /= 10;
}

if(for_pal(arr, sz) == true) kol_vo++; //проверка числа на палиндром

delete[]arr; //удаление динамического массива для создание нового(пустого) для следующего эл-та matrix[i][j]
}
cout<<"Количество чисел-палиндромов : "<<kol_vo<<endl;
}
В любом случае должно выводить хотябы 0, но не выводит нечего.
 
S

solova

Гость
#2
cout<<"Количество чисел-палиндромов : "<<kol_vo<<endl;
что бы окно осталось открытым допиши
cin.get();
возможно я ошибаюсь но,
разве не надо пересоздавать динамический массив если его размер нужно изменить?
 
R

Rififi

Гость
#3
solova

разве не надо пересоздавать динамический массив если его размер нужно изменить?

ну так у него он и пересоздаётся на каждой итерации внутреннего цикла.
только дальнейшая работа с ним всё равно ведется неправильно, так чта ожидаемое поведение программы - крэш.
 
9

9a9z9a

Гость
#4
solova

разве не надо пересоздавать динамический массив если его размер нужно изменить?

ну так у него он и пересоздаётся на каждой итерации внутреннего цикла.
только дальнейшая работа с ним всё равно ведется неправильно, так чта ожидаемое поведение программы - крэш.
Rififi, распиши, пожайлуста, как нужно сделать ;)
 
9

9a9z9a

Гость
#5
cout<<"Количество чисел-палиндромов : "<<kol_vo<<endl;
что бы окно осталось открытым допиши
cin.get();
возможно я ошибаюсь но,
разве не надо пересоздавать динамический массив если его размер нужно изменить?
он создаётся во внутреннем цикле, а после занесения цифр и проверки уничтожается
 
S

solova

Гость
#6
пересоздается в цикле? в каком? если for то sz постоянно скидывается в "0" и увеличения массива не происходит
sz = 0;
g=0;
arr = new int[sz];
while(matrix[j])
{
sz++;
arr[g++] = (matrix[j] % 10);
matrix[j] /= 10;
}
//sz=0;
//g=0;
//размер [arr]=0;
while(matrix[j])
//matrix[j]="777";
sz=1
arr[0]="7";
g=1;
matrix[j]="77"
//цикл while продолжается
sz=2
arr[1] = (matrix[j] % 10); //arr был вообще то размером 0 но и тубя стоит g++ каторая увеличивается с каждым циклом while, ты хочешь записать в не существующую ячейку

попробуй создавать массив в цикле while ведь именно он влияет на размер arr
 
9

9a9z9a

Гость
#7
solova, дай попробую объяснить.
Сначала создаётся динамический массив arr с размером sz = 0 (можно 1 - не принципиально, результат тот же), далее в цикле происходит следующее
C++:
while(matrix[i][j]) //заносит цифры в динамический массив
{
sz++; //размер массива становиться равным 1 для того чтобы занести 1-ю цифру числа
arr[g] = (matrix[i][j] % 10); //тут заносим
matrix[i][j] /= 10;//.....
g++; //переводим указатель на потенциально следующий эл-т arr[], но до того как занесем 2-й эл-т , мы увеличим и sz до 2, т.е. все правомерно

}
в итоге размер станет по-очереди 1, 2, 3, т.е. 3 , столько же цифр с числе 777. Вот этот массив мы и передаём. Может проблема в передаче динамического массива?
 
S

solova

Гость
#8
B)
динамический массив от статического отличается тем что его размер может быть задан в ходе выполнения программы
пример :
cout<<"Введите размер массива"<<endl;
cin>>razmer;
mas = new int[razmer];
а статический массив имеет размер уже заданный в программе
пример :
int *mas[ 8 ];

цикл while у тебя повторяется несколько раз т.к. (например) обрабатывает 777(3 цикла).
3 цикла=> три записи в arr => 3 ячейки => размер arr должен быть как минимум "3" , а он у тебя создан "sz=0"
и то что ты в цикле while увеличиваешь sz роли не играет,перед созданием массива стоит "sz=0;"

PS:массив создаётся во втором цикле for.
 
I

ierofant

Гость
#9
smile.gif
динамический массив от статического отличается тем что его размер может быть задан в ходе выполнения программы
пример :
cout<<"Введите размер массива"<<endl;
cin>>razmer;
mas = new int[razmer];
а статический массив имеет размер уже заданный в программе
пример :
int *mas[ 8 ];
А вот это какой по вашему массив тогда:
C++:
int size;
std::cout <<"Введите размер массива: " << std::endl;
std::cin >> size;
int mas [size];
Отличие динамических переменных от статических заключается в разном времени их жизни. Если статические переменные освобождают занимаемую ими память в конце того блока программы, в котором они были созданы. То динамические делают после вызова оператора delete.
 
S

solova

Гость
#10
ierofant
в корне неверная инициализация, именно для подобных случаев нужны динамические.
загоните свой код в компилятор и посчитайте ошибки
спешл фор ю:
вот как выглядят программы в памяти:
со статическим массивом
[Программа=;.....int size=3;..............int mas[3]= mas[0],mas[1],mas[2];............]
с динамическим массивом
[Программа=;.....int size=3;..............mas=int new [size];...................................]
[mas=;mas[0],mas[1],mas[2];]

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

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

мне показалось что "9a9z9a" решил что он один раз инициализировал массив и далее своим [g++] или увеличением "sz"он пытается увеличить размер массива.

PS: 9a9z9a, из опыта , в 90% моих случаев работы с динамическими массивами я использовал ещё динамический temp массив(временный) т.к. при увеличении массива прежние данные теряются

но если не хочешь работать с двумя массивами то ПЕРЕД созданием динамического arr узнай количество символов в matrix[j]
 
S

solova

Гость
#11
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">9a9z9a глянь сюды---вариант с одним массивом</div></div><div class="sp-body"><div class="sp-content">
C++:
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++) 
{
int count=0;
int m=matrix[i][j];
while(m)
{
count++;
m/=10;
}
arr = new int[count];
int g=0;
while(matrix[i][j]) 
{
arr[g] = (matrix[i][j] % 10); 
matrix[i][j] /= 10;
g++;
}

if(for_pal(arr, count) == true) kol_vo++; 
//насчёт твоей функции я ещё не думал но с массивами уже ты должен разобраться

delete[]arr;
}
 
I

ierofant

Гость
#12
ierofant
в корне неверная инициализация, именно для подобных случаев нужны динамические.
загоните свой код в компилятор и посчитайте ошибки
Ошибок нет. Об этом говорит и компилятор и здравый смысл. Вам следовало бы для начала самому проверить, а потом уже бросаться обвинениями. Поэтому проверьте, а потом умничайте, тем более ничего умного вы не сказали.
 
I

ierofant

Гость
#13
так вот в вашем случае(статическая инициализация) не определен размер массива в адресном пространстве программы,и программа не понимает сколько надо выделить памяти под себя.
:)
Абсолютно для всех переменных место выделяется в оперативной памяти, об этом вам скажет любая книга. Если бы переменные зашивались в коде программы, то как бы мы меняли их значение? Плохо когда человек рассказывает о вещях, о которых он понятия не имеет.
 
D

dreamer

Гость
#14
ierofant, по-моему это основы C/C++, так что коней следовало бы попридержать как раз-то Вам.
Когда в процедуре/функции объявляется статический массив, при вызове этой функции в стеке выделяется столько памяти, сколько требуется массиву (ну и остальным переменным). А поскольку size у Вас определяется в коде, компилятор не будет знать, насколько уменьшить указатель стека.
 
I

ierofant

Гость
#15
ierofant, по-моему это основы C/C++, так что коней следовало бы попридержать как раз-то Вам.
Когда в процедуре/функции объявляется статический массив, при вызове этой функции в стеке выделяется столько памяти, сколько требуется массиву (ну и остальным переменным). А поскольку size у Вас определяется в коде, компилятор не будет знать, насколько уменьшить указатель стека.
Неужели так сложно скомпилить мой код? Я вас попрошу даже, пожалуйста, попробуйте его скомпилить! А потом мы поговрим о том, кто прав, а кто нет!

А правильный ответ в том, что значение переменной size известено для компилятора в любой момент времени. И он создаст массив такого размера, который при его объявлении содержит переменная size.
 
D

dreamer

Гость
#16
Код:
error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'mas' : unknown size
А правильный ответ в том, что значение переменной size известено для компилятора в любой момент времени
Откуда оно будет известно, если в Вашем коде оно вводится с консоли?
 
I

ierofant

Гость
#18
Создание переменных происходит на этапе выполнения программы, а не на этапе компиляции. Поэтому размер будет известен, но не компилятору как выше сказал не верно.
 
9

9a9z9a

Гость
#19
Ребята, спасибо за ответы. Разобрался :)
Помогите с классом.
Есть класс , в него нужно включить путь к файлу, его размер в байтах, и некоторые методы. Как Сделать так чтобы открыть файл для всех методов?

Вот прмер:

C++:
class fs
{
int size_of_File; // размер файла
char *path_to_File; //путь к файлу
ifstream input;
public:
fs();
~fs();
void f1();
void f2();
};
fs::fs()
{
cout<<"Enter path to File:\n";
cin>>path_to_File;

ifstream input(path_to_File);
if(!input){cout<<"File "<<path_to_File<<" can`t open\n"; exit(1);}.

input.seekg(0, ios::end);
cout<<"Size of file : "<<input.tellg()<<"\n";
}
fs::~fs()
{
delete[]path_to_File;
input.close();
}
Тут методы f1() и f2() не могут работать с потоком input, видимо, потому что сразу после вызова конструктор закрывается, но ведь потом то всё равно должен оставаться открытым? :)
Можно в начале каждого метода открывать input заново, но это накладно. Помогите советом
 
I

ierofant

Гость
#20
Методы члены класса имеют доступ ко всем полям класса. Поэтому, если у вас связь осуществляется через поток input, который в вашем коде является членом класса fs, то он будет доступен для любого метода этого класса.

Вот здесь:
C++:
ifstream input(path_to_File);
Надо поменять на:
C++:
input.open (path_to_File);
Потому что у вас создаётся локальная переменная в конструкторе с таким же именем, что и член класса и работа идёт с ней.