Newsgroup: it.comp.lang.c
Titolo: Aiuto dll e deallocazione memoria

In questa DLL ci sono due funzioni e alcune variabili globali, la prima apre
una connessione verso un database LDAP e memorizza alcuni valori in
variabili globali, quando lancio la seconda funzione, questa si disconnette
dal database LDAP e (in teoria) dovrebbe rilasciare la memoria che era stata
allocata nella funzione precedente (sempre all'interno della DLL) alle
variabili globali. Ho detto in teoria, perchè in realtà ciò mi genera
"assertion failure".
Perchè fa così?
Questo problema non avrei dovuto averlo se avessi tentato di liberare la
memoria fuori dalla DLL?
Le tre istruzioni free che compaiono alla fine della funzione disconnectDB
mi generano questo problema.
Dove sbaglio?
Secondo voi per memorizzare uno stato all'interno di una DLL è consigliabile
usare delle variabili globali come sto facendo o c'è una altro metodo?
Grazie
Riccardo
#define WINSOCK
#define DOS
#define NEEDPROTOS
#define NO_USERINTERFACE
#define KERBEROS
#include <string.h>
#include <stdio.h>
#include "lber.h"
#include "ldap.h"
#include <malloc.h>
#include <memory.h>
//#include "stdafx.h"
#define DllExport  extern "C" __declspec( dllexport )
//Dichiarazioni Prototipi di funzioni da esportare
DllExport int __stdcall  ConnectDB(char* path, char* userID, char* passwd);
DllExport int __stdcall  DisconnectDB();
//Dichiarazioni Variabili Globali
LDAP * cn; //Handle della connessione
char * DB; //Variabile che memorizza il suffisso del Database aperto
char * pathDB;
bool dbOpen=false;
int __stdcall ConnectDB(char* path, char* userID, char* passwd)
/*
   Apre una connessione verso un Database. Il path del DB è specificato in
   path. Restituisce un codice negativo in caso di errore.
   Nell'implementazione basata su LDAP la funzione va in errore se
   il path non inizia per "ldap://"
*/
{
 LDAPURLDesc *srv;
 int port;
 pathDB=(char *)malloc(sizeof(path));
 strcpy(pathDB,path);
//Verifica se è un path ammissibile, in caso di errore ritorna -1
 if (ldap_is_ldap_url( path )!= 1)
  return -1;
//Alloca una struttura e fa il parse dell'url (path), ritorna -1 in caso di
errore
    if( (ldap_url_parse( path, &srv)) != LDAP_SUCCESS)
        return -1;
    else
 {
/*Verifica che la porta sia quella di default e quindi assegna alla
variabile port
la costante LDAP_PORT (389) altrimenti il valore inserito nel path, ad
esempio
ldap://
ldap.unina.it/dc=unina,dc=it
 assegna port=389
ldap://
ldap.unina.it:1050/dc=unina,dc=it
 assegna port=1050
*/
  if (srv->lud_port==0)
   port=LDAP_PORT; // Assegna 389
  else
   port=srv->lud_port;
//Alloca lo spazio per memorizzare il suffisso del Database
  DB=(char *)malloc(sizeof(srv->lud_dn));
/*Copia il suffisso specificato nel path nella variabile db
Per l'esempio visto prima si ha db=dc=unina,dc=it
*/
  strcpy(DB,srv->lud_dn);
// Apre la connessione al server e ritorna un valore negativo in caso di
errore
  cn = ldap_open(srv->lud_host, port);
  if (cn<0)
   return -1;
// Autenticazione con credenziali passate alla funzione.
  if (ldap_bind_s(cn,userID,passwd,LDAP_AUTH_SIMPLE)!=LDAP_SUCCESS)
   return -1;
// Rilascia la memoria allocata dall'API ldap_url_parse
  ldap_free_urldesc( srv );
  dbOpen=true;
  return 0;
 }
}
int __stdcall  DisconnectDB()
/*
   Chiude una connessione corrente con un DB precedentemente aperto.
Restituisce
   un codice negativo in caso di errore.
*/
{
 if (ldap_unbind_s(cn)<0)
  return -1;
 else
 {
/* Libera la memoria allocata per le variabili globali db e cn e ritorna il
valore 0
per specificare che la funzione ha operato correttamente*/
  free(cn);
  free(DB);
  free(pathDB);
  dbOpen=false;
  return 0;
 }
}

 In questa DLL ci sono due funzioni e alcune variabili globali, la prima
apre
hai postato sia su it.comp.lang.c che it.comp.lang.c++ ma questo messaggio
sulle dll, le winsock e la programmazione windows e' OT su entrambi. Prova a
postare su it.comp.programmare.win32 (se non lo hai gia' fatto, purtroppo
non e' nella lista dei NGs che posso vedere e, per quanto mi dispiaccia, non
posso partecipare).
Tommy

   free(pathDB);
[...snip...]
E ci credo che ti da problemi sulle chiamate a free()... le ultime due
chiamate sulle variabili DB e pathDB sono piene di dati inconsistenti
(spazzatura).
Saluti
R.I.

 (spazzatura).
Hai perfettamente ragione, in precedenza avevo provato strlen ma come un
pollo mi dimenticavo di sommare uno per il terrminatore (si vede che sto
alle prime armi?).
Adesso va che è un a meraviglia.
Grazie
Riccardo

 Riccardo
Di niente....
Ciao
R.I.

 memoria come un colabrodo!
Si sto spulciando il codice per deallocare tutta la memoria che mi sono
dimenticato di deallocare.
Ciao
Riccardo

 Che mi consigli?
Se non hai alcuna necessità di condividere le variabili... crea delle
variabili locali.
Se non puoi farne a meno e hai più variabili correlate tra loro perchè non
utilizzi una struttura dati con le "struct"?
Guarda un pò questo link... e vedi se ti può interessare...
http://www.accu.org/acornsig/public/articles/oop_c.html
Parla di fare OOP in C.
Saluti
R.I.