• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Po dołączeniu bibliotek do .exe Program przestaje działać [C++ BUILDER 6]

Object Storage Arubacloud
0 głosów
162 wizyt
pytanie zadane 22 sierpnia 2018 w C i C++ przez Eragoh Nowicjusz (160 p.)

Witam, korzystam z C++ BUILDER 6, wszystko działa sprawnie w programie do momentu dołączenia do .exe bibliotek (odznaczam Use Dynamic RTL oraz Build with runtime packages). Wtedy przy próbie kompilacji program wysypuje błąd: "Access Violation at address 004AFF39. Read of Address 00000000.". Po czym podświetla się linijka   : ios_base(), w nowo otwartej karcie _ios.c. Błąd może mieć jakiś związek z biblioteką fsteam.h, ale nie mam pojęcia czy i dlaczego. Dołączam kod, jeśli okaże się potrzebny.

//---------------------------------------------------------------------------

#include <vcl.h>
#include <fstream.h>
#include <windows.h>

#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "trayicon"
#pragma resource "*.dfm"
TForm1 *Form1;
int s,wczesniej;
fstream plik;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------



void Koniec(int sekundy)
{
        plik.open("TIME.txt",ios::out);
        plik.clear();
        plik<<sekundy;

        plik.close();
        Application->Terminate();
}
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
        
        AnsiString godz,min,sec;
        s++;
        int godzin,minut,sekund;
        godzin=s/3600;
        minut=(s-godzin*3600)/60;
        sekund=s-godzin*3600-minut*60;

        godz=IntToStr(godzin);
        min=IntToStr(minut);
        sec=IntToStr(sekund);

        if(godzin<10) godz="0"+godz;
        if(minut<10) min="0"+min;
        if(sekund<10) sec="0"+sec;

        Label1->Caption = godz+":"+min+":"+sec;


        int godzindzis,minutdzis,sekunddzis;
        AnsiString godzdzis,mindzis,secdzis;
        int dzis=s-wczesniej;
        godzindzis=dzis/3600;
        minutdzis=(dzis-godzindzis*3600)/60;
        sekunddzis=dzis-godzindzis*3600-minutdzis*60;

        godzdzis=IntToStr(godzindzis);
        mindzis=IntToStr(minutdzis);
        secdzis=IntToStr(sekunddzis);

        if(godzindzis<10) godzdzis="0"+godzdzis;
        if(minutdzis<10) mindzis="0"+mindzis;
        if(sekunddzis<10) secdzis="0"+secdzis;

        Label2->Caption = "Czas Dzisiaj: "+godzdzis+":"+mindzis+":"+secdzis;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
        string linia;
        plik.open("TIME.txt",ios::in);
        if ( plik.peek() == std::ifstream::traits_type::eof() )
        s=0;
        else
        plik>>s;
        wczesniej=s;
        plik.close();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
        Koniec(s);
}
//---------------------------------------------------------------------------



void __fastcall TForm1::Zakocz1Click(TObject *Sender)
{
        Koniec(s);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ResetujCzas1Click(TObject *Sender)
{
        if(Application->MessageBox("Czy na pewno chcesz zresetować czas? \n Jego aktualna wartość przepadnie!"
        ,"ARE YOU SURE?!",MB_YESNO | MB_ICONWARNING | MB_TOPMOST)==6)
        {
                remove("TIME.txt");
                s=0;
                Application->Terminate();
        }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Zmiedatstartow1Click(TObject *Sender)
{
        Form2->ShowModal();

}
//---------------------------------------------------------------------------

void __fastcall TForm1::TrayIcon1Restore(TObject *Sender)
{
        if(Form1->Visible==false)
                Form1->Show();
        else
                Form1->Hide();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Poka1Click(TObject *Sender)
{
        if(Form1->Visible==false)
                Form1->Show();
        else
                Form1->Hide();
}
//---------------------------------------------------------------------------

~~~~~~~~~~
ORAZ UNIT2:
~~~~~~~~~~

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm2 *Form2;
//---------------------------------------------------------------------------
__fastcall TForm2::TForm2(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------


void __fastcall TForm2::Button1Click(TObject *Sender)
{
        AnsiString data=Edit1->Text;
        Form1->Caption="Czas na komputerze od "+data;
        Close();

}
//------

 

komentarz 22 sierpnia 2018 przez j23 Mędrzec (194,920 p.)

Kilka uwag:

  • jest jakiś racjonalny powód, dla którego strumień plik jest globalny?
  • Nie używaj globalnego wskaźnika Form1 we wnętrzu metod klasy TForm1, chyba że wiesz, co robisz (w co wątpię).
  • linia 40: zakładanie, że timer okienkowy będzie wywoływał Timer1Timer dokładnie co sekundę jest naiwnością. Po godzinie może się okazać, że twój program naliczył nie 60 a np. 40 minut. Tak zrób:
    	time_t start_time = clock(); // gdzieś, gdzie startujesz timer
    	...
    
    	/* w TForm1::Timer1Timer */
    	int diff_time = (clock() - start_time) / CLOCKS_PER_SEC;
    
    	std::ostringstream oss;
    	oss.fill('0');
    
    	div_t d = div(diff_time, 3600);
    	oss << std::setw(2) << d.quot << ':';
    	d = div(d.rem, 60);
    	oss << std::setw(2) << d.quot << ':' << std::setw(2) << d.rem << '\n';
        
    	Label1->Caption = oss.str().c_str();

     

komentarz 22 sierpnia 2018 przez Eragoh Nowicjusz (160 p.)

Bardzo dziękuje za pomoc, rozwiązaniem mojego problemu było tak jak zaznaczył Pan w punkcie 1., przeniesienie strumienia plik z globalnego do konkretnych funkcji.

Odnośnie punktu 2. sam nie tworzyłem tego wskaźnika, Builder robi go automatycznie, przy tworzeniu nowej aplikacji. Próbowałem go usunąć z kodu w różnych aplikacjach które już robiłem, w niektórych nie ma to wpływu na poprawność kompilacji, a w innych (tej również) wyrzuca błąd:

[Linker Error] Unresolved external '_Form1' referenced from D:\...\CZAS NA KOMPUTERZE\PROJECT1.OBJ

Zapewne gdzieś, nawet nieświadomie, poprzez Interfejs buildera go użyłem. Zostawiłem ten wskaźnik, bo bez niego jest błąd, a nie zauważyłem na ten moment żadnego jego negatywnego wpływu na program.

 

W punkcie 3. natomiast dziękuję za poradę, bo tak jak powiedział Pan wcześniej, na ten moment nie wiem co robię, nie spotkałem się wcześniej z div_t, lub oss.fill, także w tej chwili nie do końca ten kod rozumiem. Uzupełnię wiedzę, i do tego wrócę.

Jeszcze raz dziękuję za Pomoc wink

komentarz 22 sierpnia 2018 przez j23 Mędrzec (194,920 p.)

Próbowałem go usunąć z kodu

Nie możesz tego wskaźnika usunąć, bo, jak sam wspomniałeś, kompilator go tam z automatu wstawia, ma jakiś ku temu powód. Chodzi o to, że odwoływanie się do metod/pól klasy z wnętrza tejże poprzez globalny wskaźnik jest a) bezsensowne b) zaciemniające kod c) błędogenne.

komentarz 22 sierpnia 2018 przez Eragoh Nowicjusz (160 p.)

Dziękuję, zapamiętam laugh

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 202 wizyt
+1 głos
3 odpowiedzi 1,663 wizyt

92,575 zapytań

141,424 odpowiedzi

319,649 komentarzy

61,960 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...