Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[WinAPI] Dynamiczne przydzielanie pamieci przez operator "new" w strukturze

Ostatnio zmodyfikowano 2012-11-25 22:22
Autor Wiadomość
berkov
Temat założony przez niniejszego użytkownika
[WinAPI] Dynamiczne przydzielanie pamieci przez operator "new" w strukturze
» 2012-11-25 21:41:23
Hey ho!

Przerabiam kolejna lekcje z kursu WinAPI - okna dialogwe i przyszedl czas dynamiczne przydzielanie pamiec i wypelnienie struktury (tu: LOGINDIALOGRESULT) wedlug wpisu do pol przez uzytkownika z dialogu (tu: WHND hwnd).


Potrzebuje dynamicznie przydzielic pamiec dla dwoch pol tekstowych (HWND hLogin i HWND hPassword) i wlozyc je odpowiednio do ldr->lpszPassword oraz ldr->lpszPassword (ldr to wskaznik na moja strukture - *ldr).

Definicja struktury (zdefiniowane globalnie):
C/C++
struct LOGINDIALOGRESULT {
    char * lpszLogin;
    char * lpszPassword;
    bool bRememberMe;
    bool bEncryption;
};
a tu juz sam kod w procedurze dialogu po kliknieciu IDOK:
C/C++
case IDOK:
{
    LOGINDIALOGRESULT * ldr = new LOGINDIALOGRESULT;
    ZeroMemory( & ldr, sizeof( LOGINDIALOGRESULT ) );
   
    HWND hLogin = GetDlgItem( hwnd, IDC_LOGIN );
    HWND hPassword = GetDlgItem( hwnd, IDC_PASSWORD );
    HWND hRememberMe = GetDlgItem( hwnd, IDC_REMEMBERME );
    HWND hEncryption = GetDlgItem( hwnd, IDC_COMBOBOX );
   
    DWORD dlugosc = GetWindowTextLength( hLogin );
    ldr->lpszLogin = new char[ dlugosc + 1 ];
    MessageBeep( 0 );
    GetWindowText( hLogin, ldr->lpszLogin, dlugosc + 1 );
   
    dlugosc = GetWindowTextLength( hPassword );
    ldr->lpszPassword = new char[ dlugosc + 1 ];
    GetWindowText( hPassword, ldr->lpszPassword, dlugosc + 1 );
   
    ldr->bRememberMe =( IsDlgButtonChecked( hwnd, IDC_REMEMBERME ) == BST_CHECKED );
   
    ldr->bEncryption =( bool )( ComboBox_GetCurSel( hEncryption ) );
   
    EndDialog( hwnd,( int ) ldr );
}
break;
Kompilator kompiluje bez problemu ale po odpaleniu programu w miejscu wykonania
ldr->lpszLogin = new char[ dlugosc + 1 ];
 dostaje nastepujacy blad:
Unhandled exception at 0x00E230A3 in [NAZWAEXE].exe: 0xC0000005: Access violation writing location 0x00000000
czy przydzielenie dynamiczne pamieci w przypadku struktur jakos sie rozni?
to kod zywcem sciagniety z kursu wiec pomyslalbym ze bedzie dzialal bez problemu.


czy ktos wie dlaczegoz?


p.s.
btw, czy ktos w jedyn zdaniu by mi mogl wytlumaczyc czym rozni sie ldr.lpszLogin = x od ldr->lpszLogin bo przyznaje ze srednio to zalapalem.


z gory dzieki
berkov
P-69892
Mrovqa
» 2012-11-25 21:52:24
Kompilator kompiluje bez problemu ale po odpaleniu programu w miejscu wykonania ldr->lpszLogin = new char[ dlugosc + 1 ]; dostaje nastepujacy blad:

Unhandled exception at 0x00E230A3 in [NAZWAEXE].exe: 0xC0000005: Access violation writing location 0x00000000
To by wskazywało na to, że ldr zawiera NULL. Choć to jest trochę dziwne, bo nie korzystasz wcześniej z std::nothrow: LOGINDIALOGRESULT *ldr = new LOGINDIALOGRESULT;
P-69894
cyklopek11
» 2012-11-25 21:58:58
Problem jest w:
C/C++
ZeroMemory( & ldr, sizeof( LOGINDIALOGRESULT ) );
&ldr to adres wskaźnika na strukturę LOGINDIALOGRESULT i zerujesz wskaźnik. Adres do struktury to sam ldr.  Usuń znaczek & i masz:
C/C++
ZeroMemory( ldr, sizeof( LOGINDIALOGRESULT ) );
P-69895
berkov
Temat założony przez niniejszego użytkownika
» 2012-11-25 22:05:13
WYPAS!!! .. dziala!


mistrzu jestes wielki! :-)
dziekuje.
P-69896
cyklopek11
» 2012-11-25 22:06:06
Nie jestem mistrzem, dopiero się uczę :-) A nic tak nie uczy jak szukanie/usuwanie błędów własnych i obcych.
P-69897
berkov
Temat założony przez niniejszego użytkownika
» 2012-11-25 22:13:23
:-)


no to musze powiedziec ze jak na poczatkujacego to masz niezle ostre oko...

jak juz cie tu mam to mozesz rzucic troche swiatla na roznice miedzy dostaniem sie w strukturze do zmiennej przez -> albo .? (STRUKTURA.zmienna a STRUKTURA->zmienna) .. zawsze proboje i jedno i drugie i ktores wyjdzie ale nie zrozumialem roznicy a kurs w tym temacie byl troche cienki (albo to ja bylem cienki!).

b.
P-69898
cyklopek11
» 2012-11-25 22:19:53
C/C++
struct MojaStruktura { // prosta globalna definicja
   
    int poleA;
    double poleB;
   
};


// gdzieś w funkcji main

MojaStruktura zmienna1; // tworzymy zmienną
zmienna1.poleA = 10; // ustawiamy wartości pól
zmienna1.poleB = 9.9;
MojaStruktura & referencjaZmienna1 = zmienna1; // tworzymy referencję do zmiennej zmienna1
referencjaZmienna1.poleA = 74; //ustawiamy wartości zmiennej1 przez referencję
referencjaZmienna1.poleB = 22.66;

MojaStruktura * wskaznikNaStrukture = & zmienna1; // tworzymy wskaxnik który ma pokazywać na zmienna1
wskaznikNaStrukture->poleA = 33; // poprzez ten wskaźnik ustawiamy pola zmiennej1
wskaznikNaStrukture->poleB = 11.98;
 
P-69899
Savail
» 2012-11-25 22:20:50
Jeśli obiekt twojej struktury jest wskaźnikiem, czyli zdefiniowany np. w ten sposób:
STRUKTURA * S = new STRUKTURA;
 to aby dostać się do pól struktury używasz operatora "->"

A jeśli tworzysz zwykły obiekt struktury:
STRUKTURA S;
 to do pól odnosisz się używając operatora "."

W WinAPI często używa się właśnie wskaźników na różne struktury. Nie wiem jak w innych IDE ale w Visual C++ wyświetla się dymek po najechaniu na funkcję i pokazuje jaki parametr funkcja zwraca / przyjmuje, czy jest to wskaźnik czy nie.
P-69900
« 1 » 2
  Strona 1 z 2 Następna strona