• 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]

Hosting forpsi easy 1 pln
0 głosów
156 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,340 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,340 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ź 165 wizyt
+1 głos
3 odpowiedzi 1,587 wizyt

92,125 zapytań

140,785 odpowiedzi

317,804 komentarzy

61,446 pasjonatów

Advent of Code 2023

Top 15 użytkowników

  1. 1468p. - Łukasz Eckert
  2. 1444p. - Dawid128
  3. 1430p. - CC PL
  4. 1419p. - rafalszastok
  5. 1418p. - Marcin Putra
  6. 1373p. - Mikbac
  7. 1362p. - rucin93
  8. 1351p. - sefirek
  9. 1325p. - Michal Drewniak
  10. 1296p. - Adrian Wieprzkowicz
  11. 1267p. - Eryk Andrzejewski
  12. 1260p. - TheLukaszNs
  13. 1239p. - JarekDev
  14. 1188p. - Rafał Trójniak
  15. 1179p. - 13NOONE37
Szczegóły i pełne wyniki

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.

Uwaga - w dniach od 02.12 do 08.12 trwają Mikołajki (książki drukowane mają rabat -35%, ebooki do -45%). Zaś dodatkowy, specjalny kod zniżkowy: HELMIKOLAJ-10 dla naszych Widzów zapewni Wam oszczędność -10zł dla zamówień powyżej 70zł! Warto korzystać!

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...