Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    [C++] Incomprensione con puntatori

    Salve a tutti ragazzi, oggi per la prima volta dopo due anni sto avendo problemi con i puntatori.
    Diciamo che è la prima volta che mi compare un inghippo del genere.

    codice:
    std::string Report::WSAGetLastError()
    {
    	int iError = ::WSAGetLastError();
    	LPSTR buffer = NULL;
    	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,0,iError,LANG_USER_DEFAULT,(LPSTR)&buffer,0,NULL);
    	std::string error = buffer;
    	return error;
    }
    Il codice funziona, mentre se invece di passare come paramentro (LPSTR)&buffer, passo solamente buffer, oppure &*buffer, non va!

    Spiego il mio ragionamento:
    LPSTR è un char *, quindi se passo un char * lui dovrebbe riuscire ad allocarci memoria, perchè gli passo l'indirizzo del puntatore, eppure non è così.

    Se invece passassi &*buffer, dovrebbe andare perchè passo l'indirizzo del char a cui punta il puntatore, ma non è così!

    Invece se passo &buffer, che in realtà non è un char * ma un char **!!!! e lo casto a char * funziona! non capisco minimamente il senso di questo comportamento, perfavore aiutatemi voi

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    E' tutto spiegato nelle note dell'opzione FORMAT_MESSAGE_ALLOCATE_BUFFER, che tu usi

    The function allocates a buffer large enough to hold the formatted message, and places a pointer to the allocated buffer at the address specified by lpBuffer. The lpBuffer parameter is a pointer to an LPTSTR; you must cast the pointer to an LPTSTR (for example, (LPTSTR)&lpBuffer). The nSize parameter specifies the minimum number of TCHARs to allocate for an output message buffer. The caller should use the LocalFree function to free the buffer when it is no longer needed.

    E ti faccio notare che, nel tuo codice, manca la chiamata (necessaria) alla LocalFree.

    Nel caso non usassi l'opzione FORMAT_MESSAGE_ALLOCATE_BUFFER, allora dovresti allocare (e liberare) tu il buffer e passare semplicemente il puntatore.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    Grazie

    Avevo letto quel pezzo, comunque grazie per la LocalFree(), mi ero dimenticato di metterla. Però resta il fatto che secondo me almeno non ha senso logico la conversione tra un char ** e un char * che indicano due cose completamente diverse! Non mi va proprio giù questa cosa.

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Allora ... come prima modalità di chiamata della funzione si ha che tu allochi il buffer e tu lo liberi. Dato che lo allochi, passi il puntatore al buffer e la sua lunghezza (quindi il parametro è un semplice LPSTR). Questo metodo è senza l'opzione FORMAT_MESSAGE_ALLOCATE_BUFFER .

    Ma puoi usare la funzione in un altro modo, ovvero facendo allocare lo spazio dalla funzione stessa e liberandolo tu. In questo caso devi indicare l'opzione FORMAT_MESSAGE_ALLOCATE_BUFFER e sorge un problema: il parametro semplice puntatore non va più bene (dato che il puntatore deve essere restituito); per questo motivo passi un puntatore a puntatore e, tramite un cast a LPSTR, tieni a bada il controllo di tipo del compilatore per evitare messaggi d'errore.
    In fondo, quello che conta, è che l'indirizzo passato sia quello di un puntatore a puntatore.

    Un modo per ottenere, con la stessa funzione, due comportamenti (ricorda che si tratta di C e non C++).

    Il punto importante di questa discussione è che la cosa sia ben documentata e mi pare che lo sia.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    hai provato come nell'esempio?

    codice:
    #ifndef UNICODE
    #define UNICODE
    #endif
    
    #include <windows.h>
    #include <stdio.h>
    
    void main(void)
    {
        LPWSTR pMessage = L"%1!*.*s! %4 %5!*s!";
        DWORD_PTR pArgs[] = { (DWORD_PTR)4, (DWORD_PTR)2, (DWORD_PTR)L"Bill",  // %1!*.*s! refers back to the first insertion string in pMessage
             (DWORD_PTR)L"Bob",                                                // %4 refers back to the second insertion string in pMessage
             (DWORD_PTR)6, (DWORD_PTR)L"Bill" };                               // %5!*s! refers back to the third insertion string in pMessage
        const DWORD size = 100+1;
        WCHAR buffer[size];
    
    
        if (!FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
                           pMessage, 
                           0,
                           0,
                           buffer, 
                           size, 
                           (va_list*)pArgs))
        {
            wprintf(L"Format message failed with 0x%x\n", GetLastError());
            return;
        }
    
        // Buffer contains "  Bi Bob   Bill".
        wprintf(L"Formatted message: %s\n", buffer);
    }
    Administrator of NAMDesign.Net

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Un piccolo suggerimento.
    Dato che stai forzando l'uso specifico di atd::string e LPSTR, dovresti invocare FormatMessageA, altrimenti se le macro per unicode sono impostate, FormatMessage diventa FormatMessageW con tutti gli errori del caso.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.