• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Fstream некорректно работает. Хелп!?

  • Автор темы shadowofjustice
  • Дата начала
Статус
Закрыто для дальнейших ответов.
S

shadowofjustice

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

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

Стоит отметить, что все переменные объявлены одинаково. И, кстати, что примечательно. Если в первом проекте не создавать файл в начале, а сразу попробовать прочитать - то тоже все схватывает хорошо. :/ Суть проблемы понять не могу. Файл один и тот же, реализация одна. Результаты разные.

Приведу примеры кода:

Все в одном проекте
C++:
int mem;
mem=8*5;
double *matr;
matr=(double *)malloc(mem*sizeof(double));

/*тут идет заполнение матрицы*/

fstream output;
output.open("inA.txt",ios_base::out|ios_base::trunc);
output.write((char *)&matr,sizeof(matr));
output.close();

double *A;
A=(double *)malloc(mem*sizeof(double));

ifstream input;
input.open("inA.txt",ios_base::in);
input.read((char *) &A,sizeof(A));
input.close();

В другом проекте:
C++:
mem=8*5;
double *A;
A=(double *)malloc(mem*sizeof(double));

ifstream input;
input.open("inA.txt",ios_base::in);
input.read((char *) &A,sizeof(A));
input.close();
 
I

ierofant

В певом проекте работа идёт с тектовым файлом, во втором с бинарным. Так и задумано?


Добавлено: Флаг ios_base::binary во втором проекте попробуйте поменять на ios_base::in
 
S

shadowofjustice

В певом проекте работа идёт с тектовым файлом, во втором с бинарным. Так и задумано?
Добавлено: Флаг ios_base::binary во втором проекте попробуйте поменять на ios_base::in

да, сорри за неточность.
там на самом деле было ios_base::in

я пробовал и бинарный формат тоже в обоих случаях. Ни при out;trunc и in, ни в бинарном виде - не работает :(
 
I

ierofant

C++:
input.read((char *) &A,sizeof(A));

A ведь и так указатель. Зачем вы передаёте указатель на указатель?
 
I

ierofant

Посмотрите ещё раз предыдущее сообщение. Из-за того что мы с вами пмшем в одно время, всё запутолось.
 
S

shadowofjustice

и еще. что примечательно:
когда только выделиляется память под A - ее первое значение по адресу *А = -6.2774385622041925e+066 (и соответсвенно *(А+1)=-6.2774385622041925e+066, *(А+2)=-6.2774385622041925e+066 и т.д. ),
затем после чтения из файла значения меняются на -2.6569842580370804e+303. В файле, естественно, хранятся не такие числа.
Это скорее всего из-за того, что адрес памяти меняется почему-то после чтения. Хотя он меняется после чтения в обоих проектах, но во втором выводит как раз некорректные значения.

Добавлено:
Посмотрите ещё раз предыдущее сообщение. Из-за того что мы с вами пмшем в одно время, всё запутолось.
нет, по прежнему не помогает :(
 
I

ierofant

C++:
((char *)&matr,sizeof(matr))
((char *) &A,sizeof(A))
Везде поменяйте на:
C++:
((char *) matr,sizeof(mem*sizeof(double)))
((char *) A,sizeof(mem*sizeof(double)))


Добавлено: Потому что вы сохранеяте не переменную, а её адрес.
 
S

shadowofjustice

C++:
((char *)&matr,sizeof(matr))
((char *) &A,sizeof(A))
Везде поменяйте на:
C++:
((char *) matr,sizeof(mem*sizeof(double)))
((char *) A,sizeof(mem*sizeof(double)))


Добавлено: Потому что вы сохранеяте не переменную, а её адрес.


хмм. нет, не помогает. Таким образом он вобще ничего не выводит в файл.
и Вы допустили ошибку, сказав чуть выше, что я передаю указатель на указатель вот тут:
C++:
input.read((char *) &A,sizeof(A));
& Это ж вроде ссылка на переменную. а (char *) - это приведение к типу. Т.е. получается я указываю на адрес памяти, где начало матрицы А и считываю оттуда sizeof(A) байт.
или я что-то путаю. в общем - то вопрос не в этом. В первом проекте все работает корректно с таким кодом. Он, кстати, взят из книжек. Почему я не могу размножить этот файл и читать его разными проектами. вот в чем дело :(
 
I

ierofant

Нет я всё верно сказал!
double *matr; это указатель

a & - это оператор взятия адреса. &matr - это указатель на указатель.

C++:
output.write((char *)&matr,sizeof(matr));
Здесь вы записываете адрес указателя в файл. В одной программе у вас всё работает, потому что адреса все те же самые. Вы же видите, что в файле у вас совершенно не те данные.
 
I

ierofant

Вот этот код работает:
C++:
#include <iostream>
#include <fstream>

int main ()
{
int size = 8*5;
double *mass = new double [size];
for (int i = 0; i < size; i++) mass [i] = i;

std::ofstream out ("file", std::ios::out | std::ios::trunc);
out.write ((char*) mass, size * sizeof (double));
out.close ();

double *a = new double [size];
std::ifstream in ("file");
in.read ((char*) a, size * sizeof (double));
in.close ();

for (int i = 0; i < size; i++) std::cout << a [i] << std::endl;
delete[] mass, a;
return 0;
}
 
I

ierofant

Только мне не понятно, зачем вам нужны массивы именно в динамической памяти... Не легче ли обычный массив создать.
 
S

shadowofjustice

О, спасибо! точно! теперь дошло до меня вроде бы!! вот почему файл получается всего 4 байта всегда. :(
насчет динамического массива - моя программа будет работать с большимим объемами данных (матрицы порядка 1000000 на 1000000) и заранее размер будет неизвестен. Эти матрицы хранятся в бинарном файле. Мне необходимо их будет загрузить в оперативную память и обработать.
кстати Ваш пример будет работать с динамическими массивами? я похоже слабо понимаю в указателях\ссылках, поэтому как мне адаптировать Ваш код под динамические массивы любой величины?
Огромное спасибо!!
 
I

ierofant

C++:
double *mass = new double [size];
Вот динамический массив создаётся размером size.
 
S

shadowofjustice

а если я все же malloc буду применять? суть не изменится?
или возникнут подводные камни?
 
I

ierofant

malloc это функция языка C, оставленная в С++ для совместимости.
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

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