Newsgroup: it.comp.programmare.win32
Titolo: Problema con allocazione di memoria con funzioni e puntatori

Ciao a tutti!
Non so se sia più giusto postare quio sul ng del C,
cmq trattandosi di windows...
Ho creato una funzione che dato un "titolo",
verifica se esiste un messaggio di errore con quel titolo,
e ne recupera il testo.
Alla funzione passo il titolo,
e un puntatore char *wintxt non inizializzato.
All'interno della funzione, verificata la lunghezza del messaggio,
alloco la memoria necessaria a contenerlo,
faccio una piccola modifica, e poi esco.
Il problema è che quando torno nel main,
wintxt risulta ancora non inizializzata: come mai?
ho l'impressione di aver fatto qualche errore concettuale.
Spero possiate aiutarmi.
Mille grazie
ecco il codice:
<CODE>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int find_window(char *prg,char *win_msg)
{
   HWND hWnd;
   HWND fhWnd;
   int win_txt_len,i,j;
   char *tmp; //testo originale del messaggio
         printf("find_window -> Controllo: %s\r\n",prg);
   hWnd = FindWindow(NULL,prg);
   if (hWnd == 0)  {
                 printf("find_window -> Cannot find window!\r\n");//debug
         return 0;
   }
   else {
         printf("find_window -> trovata finestra %s.\r\n",prg);//debug
     fhWnd=GetDlgItem(hWnd,0xFFFF);
                 printf("find_window -> Dopo GetDlgItem.\r\n");//debug
     if(fhWnd) {
           win_txt_len = GetWindowTextLength(fhWnd);
                   printf("find_window ->  Si tratta di Message Box; 
len: %d.\r\n",win_txt_len);//d
ebug
       tmp = (char *)calloc(win_txt_len+2,sizeof(char));
           if (!tmp) {
                    printf("find_window -> memoria per tmp non 
allocata!!!\r\n");
                    return -1;
     }
           else
                         printf("find_window -> memoria per tmp 
allocata!!!\r\n");
           if (win_msg)
                   free(win_msg);
     win_msg = (char *)calloc(win_txt_len+60,sizeof(char));
     if (!win_msg)
                         printf("find_window -> memoria per win_msg non 
allocata!!!\r\n");
           else
                         printf("find_window -> memoria per win_msg 
allocata!!!\r\n");
       GetWindowText(fhWnd,tmp,2000);
                   printf("find_window -> Dopo GetWindowText.\r\n"); //debug
                   printf("find_window -> testo originale-> %s \n",tmp);
       for (i=0;tmp[i] != '\0' && i<win_txt_len;i++){
          if (tmp[i] == '\n') {
            win_msg[j++]='\r';
          }
              win_msg[j++]=tmp[i];
       }
       win_msg[j++]='\0'; free(tmp);
                 printf("OK ->Esco da findwindow.\r\n"); //debug
           return 1;
     }
                 printf("Esco da findwindow.\r\n"); //debug
     return 0;
   }
}
int main(int argc, char *argv[])
{
   char *wintxt;
   int fw_res=find_window("Exception Caught",wintxt);
   printf ("valore restituito: %d\n",fw_res);
   if (fw_res == 1) {
     printf ("trovato questo testo: %s\n",wintxt);
   }
   system("PAUSE");
   return 0;
}
                   printf("find_window -> testo sistemato-> %s\n",win_msg);
</CODE>

 ho l'impressione di aver fatto qualche errore concettuale.
Domenticavo di dire una cosa importante.
Se invece che fare l'allocazione di memoria all'interno della funzione,
la faccio nel main, con un calloc
o staticamente con un array di caratteri,
il problema non si presenta:
tornato al main, ho il completo testo del messaggio.
In questo modo perň, devo impormi a priori un limite sulla lunghezza del 
messaggio che posso leggere.
Grazie ancora

 ho l'impressione di aver fatto qualche errore concettuale.
Esatto, l'errore č concettuale. In C le variabili vengono sempre passate per
copia. Ovvero se tu passi una variabile ad una funzione, questa variabile
non puň essere modificata dalla funzione stessa, o meglio la variabile viene
copiata e la funzione modifica la copia che quindi al termine della funzione
non viene ripassata alla variabile originale.
Soluzioni:
a) usare il Pascal (costrutto var nella definizione dei parametri), oppure
il C++ (il parametro viene passato come riferimento facendolo precedere da
un &).
b) usare un puntatore alla variabile. Semplice e facile. Nel tuo caso basta
modificare la funzione in modo che diventi:
int find_window(char *prg,char **win_msg)
all'interno della funzione invece che usare win_msg usi (*win_msg), ovvero
dereferenzi il puntatore.
poi invochi la funzione nel main cosě:
int fw_res=find_window("Exception Caught",&wintxt);
-- 
/* Costantino Grana                                */
main(int c,char**o){char*s=c?"+L7?+;:7?+:OKIK+9?;9=;"
":+9?;:<:;+9?;;;:;+9<:;<::;+RLJ;K9+":1[o],t,a=!c,m;do
for (m=*s-'0',t=a?m/c:m%c;m>>7?c=1<<m+8,!a&&puts(&a)*
*&a:t--;printf("  \0/*"+a));while ((a^=3)||a[++s]);;}
/* Original code due to Chris Brown... impressive! */

 ha scritto:
Testato e funzionante:
int find_window (char *prg,char **win_msg)
{
HWND hWnd;
HWND fhWnd;
int win_txt_len,i,j;
char *tmp,*p2;
hWnd = FindWindow (NULL,prg);
if (hWnd == 0)
   return 0;
else
   {
   fhWnd = GetDlgItem (hWnd,0xFFFF);
   if (fhWnd)
      {
      win_txt_len = GetWindowTextLength (fhWnd);
      tmp = (char *) calloc (win_txt_len+2,sizeof (char));
      if (!tmp)
         return -1;
      if (*win_msg)
         free (*win_msg);
      p2 = (char *) calloc (win_txt_len+60,sizeof(char));
      if (!p2)
         return -1;
      GetWindowText (fhWnd,tmp,win_txt_len);
j = 0;
      for (i=0;tmp[i] != '\0' && i<win_txt_len;i++)
         {
         if (tmp [i] == '\n')
            p2 [j++] = '\r';
         p2 [j++] = tmp[i];
         }
      p2 [j++]='\0';
      free (tmp);
      *win_msg = p2;
      return 1;
      }
   return 0;
   }
}
int main (int argc, char *argv[])
{
char *wintxt = NULL;
int fw_res = find_window ("Exception Caught",wintxt);


 
Perfetto, vi ringrazio entrambi!!!
In effetti dovrei vergognarmi per non esserci arrivato da solo :p
In ogni caso resta solo una domanda:
perchè è obbligatorio inizializzare il puntatore con NULL nel main?
Grazie ancora.
bye ;-)

 perchè è obbligatorio inizializzare il puntatore con NULL nel main?
Perché hai fatto un programma che verifica se il puntatore è NULL e, se non 
lo è, fa una free. Ovviamente se fai una free di un'area di memoria a caso 
causi un errore. Quindi la prima volta lo metti a NULL, cioè a 0.


 
Decisamente lineare.
Mille grazie