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;
 }
}

  strcpy(pathDB,path);
va a scrivere oltre il dovuto
al posto di sizeof(path) avresti dovuto usare la strlen.
Analogamente fai attenzione alle altre malloc.
Il problema non e' detto che ti si presenti subito ma dipende da quali dati
vitali sei andato a sporcare poi con le strcpy.
Maurus

 vitali sei andato a sporcare poi con le strcpy.
Grazie Maurus, in precedenza avevo già provato con stllen ma l'effetto era
sempre lo stesso, poi mi hanno fatto notare che effettivamente il metodo
giusto è usare stllen+1 (già +1 avevo dimenticato il terminatore) per questo
falliva, adesso è OK!
Grazie ancora.
Ciao
Riccardo