Błąd przy usuwaniu tablicy dynamicznej

0

Witam, czy ktoś potrafi powiedzieć dlaczego w tym kodzie jest błąd?

#include <iostream>
#include <fstream>

using namespace std;
int pojemnosc = 100;
int main()
{
    bool *bufor = new bool [pojemnosc];


        ifstream odczyt("litera.bin", ios_base::binary );
        odczyt.read((char*) &bufor, sizeof(bufor));
        odczyt.close();
        delete [] bufor;
        bufor = NULL;
} 

Wiem że przez tą linijkę

odczyt.read((char*) &bufor, sizeof(bufor)); 

wyskakuje błąd dotyczący pamięci.
Zapisywanie do pliku funkcją

 .write

wygląda prawie identycznie, a jednak tam nie ma problemów z usunięciem tablicy.
Proszę o pomoc i przepraszam jeśli coś niezrozumiale napisałem, ale siedzę już nad tym całą noc i szukam rozwiązania.

1

Wiem że przez tą linijkę
odczyt.read((char*) &bufor, sizeof(bufor));

Podajesz rozmiar wskaźnika zamiast długości tablicy i na dodatek robisz bezsensowne rzutowanie (bufor jest wskaźnikiem!). Pomyśl co będzie jego wynikiem.
Zaglądnij do dokumentacji http://www.cplusplus.com/.
Jest parę innych niedociągnięć. Nie sprawdzasz czy plik rzeczywiście został otworzony, odczyt się powiódł, zbyt wcześnie alokujesz pamięć na wczytywane dane. No i przydałoby się dopisać return.

0

Moje pytanie brzmi: Po co robisz tablicę typu bool a potem rzutujesz i "wczytujesz" do niej typy char ?
Nie lepiej stworzyć od razu zmienną typu char ?

0

A dlaczego to działa?

ofstream zapis("litera.bin", ios_base::binary);
        zapis.write((char*) &bufor_zapis, sizeof(bufor_zapis));
        zapis.close(); 

I ładnie wszystko zapisuje do pliku, z którego później mogę załadować dane do "bufor" i wypisać na ekran, ale nie mogę na koniec usunąć tej tablicy "bufor".

Albo zapytam inaczej... Czy jest jakiś sposób aby zapisać tablice typu bool binarnie do pliku?

EDIT: Dobra temat już nieważny. Poszedłem po rozum do głowy i zrezygnowałem z fanaberii tworzenia tablicy bool i po prostu zapisuje i odczytuje to jako tablice char z zerami i jedynkami. Przepraszam za zawracanie głowy:)

0

ręce opadają (głównie dlatego, że nikt nie widzi najważniejszego błędu). To powinno by tak:

include <iostream>
#include <fstream>

using namespace std;
int pojemnosc = 100;
int main()
{
    bool *bufor = new bool [pojemnosc];
    ifstream odczyt("litera.bin", ios_base::binary );
    odczyt.read((char*)bufor, sizeof(*bufor)*pojemnosc); // a gdzie się podział twój ampersand!!!
    odczyt.close();
    delete [] bufor;
    bufor = NULL;
} 

ty wczytywałeś/zapisywałeś ADRES wskaźnika i na tym poległą błąd i dlatego miałeś seg fault-a.

0

Tylko po co zapisywać binarnie? Procesor nie lubi czytać po 1 bicie. Nie po to ma rejestry 32bitowe. Poza tym 100 bitów = 25bajtów. Można zapisać jako int_32. Do tego mogę jeszcze dodać, że jeżeli rozmiar tablicy będzie niepodzielny na 4 to zawsze możesz zmienić ostatnie bity na bajt dopisując 0. Przy tym rozwiązaniu musisz na początku pliku wpisać wielkość danych.

Zapis do pliku:

  //Otwarcie pliku, sprawdzenie poprawności etc.
 extern int rozmiar; //Gdzieś zdefiniowany rozmiar tablicy w bitach.

char* Tablica = new char[ (int(rozmiar / 8)) + 1 ];
ZeroMemory( Tablica, (int(rozmiar / 8)) + 1 );


  //zapis bit po bicie
int curr;
for( int bitnum = 0; bitnum < rozmiar; ++bitnum)
{
    cin>>curr;
    cin.ignore();

    curr %= 2; //obcinamy do 0/1
   
     //1 bajt to 8 bitów
    Tablica[(bitnum / 8)] = curr << ( 7 - (bitnum % 8)); //przekształcamy 0000 0001 na 1000 0000 etc.
}


//kopiowanie bitów z pamięci
extern bool* Source;
memcpy( Tablica,  Source, rozmiar);

Odczyt z pliku:

  //Otwarcie pliku, sprawdzenie poprawności etc.

int rozmiar;
odczyt>>rozmiar;

char* Tablica = new char[ (int(rozmiar / 8)) + 1 ];
ZeroMemory( Tablica, (int(rozmiar / 8)) + 1 );

odczyt.read((char*)Tablica, rozmiar);  //Wczyta z pliku wcześniej zdefiniowana ilość danych, reszta zostanie zerami 
0

Generalnie sprawa wygląda tak:
Kod w pierwszym poście jest wycięty z reszty programu bo chciałem przedstawić tylko istotną część.
Mam klase w której są, miedzy innymi "szerokosc", "wysokosc" i "rozmiar_naglowka". Poza tym deklaruje jeszcze wskaźnik na typ char char * bufor_odczyt; Tą "pojemnosc = 100" podałem tylko przykładowo. W rzeczywistości zmienia się ona w zależności od tych trzech parametrów.

Ostatecznie zrobiłem to tak:

 void JAKAS_KLASA::Wczytywanie()
{
    bufor_odczyt = new char [szerokosc * wysokosc + rozmiar_naglowka];

    string sciezka_dostepu = obiekt_jakiejs_innej_klasy.UtworzSciezke();

    ifstream odczyt(sciezka_dostepu.c_str(), ios_base::binary);
    odczyt.read(bufor_odczyt, (szerokosc * wysokosc + rozmiar_naglowka));
    odczyt.close();
}
delete [] bufor_odczyt;

jest w destruktorze.

0

No dobrze, ale co on odczytuje z tego pliku? To są wartości true/false dla każdego piksela? Jeśli tak to dużo tracisz na takim rozwiązaniu.

0

Jeśli uważasz, że ten kod przystaje do kodu jaki dałeś na początku to gratuluje pomysłowości.
Jeśli uważasz, że taki mały wycinek twojej klasy pozwala stwierdzić cokolwiek użytecznego, to gratuluje naiwności.

Wróżąc z fusów: w konstruktorze nie zerujesz bufor_odczyt i destruktor próbuje deblokować śmieci, albo gdzieś robisz klona obiektu a masz tylko domyślny konstruktor kopiujący.


*Update*: IMO w obecnym stanie wątek nadaje się jedynie do kosza, powinieneś założyć nowy wątek z porządnym opisem problemu.
0

@ Ola Nordmann
Program tworzy bitmape ze screenem w pamięci. Na obrazku są litery i cyfry które muszę odczytać. Jako że kontrast miedzy literami i tłem jest duży, łatwo ustalić od jakiego progu wartości składowych RGB piksel istnieje albo nie. I to mi wystarcza. Później tylko wczytuje odpowiednie obszary bitmapy zajmowane przez litery. Teraz żeby dowiedzieć się jaka to litera muszę porównać ją z czymś co zna już program(można to nazwać matrycą). I właśnie te stworzone przeze mnie i zapisane już w plikach matryce chce wczytać do pamięci.

0

Taki OCR. W takim razie nie opłaca się wartości bool zapisywać w char. Lepiej zrobić tablicę elementów typu bool, zaokrąglić ją do liczby podzielnej przez 8 w górę i na twardo rzutować na bool. Przy zapisie odwrotnie. Będzie mniejszy plik a dostęp do danych identyczny ( procesor i tak z tego boola zrobi dla siebie char ).

1 użytkowników online, w tym zalogowanych: 0, gości: 1