Je sais que je réinvente la roue mais étant débutant en c++ je soumets ma première source aux commentaires.
Son but est aussi pédagogique pour les débutants qu'inutile pour les autres.
Cette classe permet de gérer un tampon de char géré par HeapAlloc(), HeapRealloc(), et HeapFree()
Les méthodes sont les suivantes :
// Constructeur permettant de spécifier la taille initiale du tampon
XCharBuffer(const unsigned int p_iSize);
// GESTION DE LA TAILLE
bool setBufferSize(const unsigned int p_size); // Défini la taille du tampon
bool pack(); // Ajuste la taille du tampon au contenu
unsigned int getValueSize(); // Retourne la taille de la chaine contenu (sans le \0)
unsigned int getBufferSize(); // Retourne la taille du tampon
// GESTION DU CONTENU
void clear(); // Efface le contenu du tampon
void append(const char* p_pszValue); // Ajoute une chaine
char* toCharArray(); // Retourne le contenu (char*)
Cette peut être spécialisée car les méthodes de gestion du tampon sont protected
Source / Exemple :
// XCharBuffer.h
#include "Windows.h"
class XCharBuffer
{
public:
// GESTION DE L'INSTANCE
// Construteurs
XCharBuffer(const unsigned int p_iSize);
// Déstructeur
virtual ~XCharBuffer();
// GESTION DE LA TAILLE
// Défini la taille du tampon
bool setBufferSize(const unsigned int p_size);
// Ajuste la taille du tampon au contenu
bool pack();
// Retourne la taille de la chaine contenu (sans le \0)
unsigned int getValueSize();
// Retourne la taille du tampon
unsigned int getBufferSize();
// GESTION DU CONTENU
// Efface le contenu du tampon
void clear();
// Ajoute une chaine
void append(const char* p_pszValue);
void append(const unsigned char* p_pszValue);
// Retourne le contenu (char*)
char* toCharArray();
// Retourne le contenu (BSTR)
//const BSTR* toCharArray();
protected:
HANDLE m_hHeapHandle; // Handle du Tas contenant le buffer
char *m_pszBuffer; // Tampon de stockage
char *m_pBufferPos; // Pointeur sur le prochain caratère à ecrire
char *m_pBufferPosMax; // Pointeur sur le prochain caratère à ecrire
unsigned int m_iBufferSize; // Taille allouée au tampon
unsigned int m_iValueSize; // Taille de la valeur contenue
// Crée ou agrandi le buffer si necessaire pour y stocker (p_iSize) nouveaux caractères
inline bool increaseBuffer(const unsigned int p_iSize);
// Redéfinie la taille du tampon existant à (p_iSize) caractères
inline bool resizeBuffer(const unsigned int p_iSize);
// Retourne la taille de la chaine sans le \0
inline unsigned int getLength(const char* p_pszValue);
// Copie les (p_iSize) caractères du buffer (source) vers le buffer (target)
inline void copyBuffer(const char* p_pszSrcValue, char* p_pszTrgValue, unsigned int p_iSize);
};
__________________________________________________________________________________________________
// XCharBuffer.cpp
#include "XCharBuffer.h"
/***********************************************************************
*
*
/****************************************************************
// Construteur
XCharBuffer::XCharBuffer(const unsigned int p_iSize)
{
// Définition du tas à utiliser
this->m_hHeapHandle = GetProcessHeap();
this->m_pszBuffer = NULL; // Tampon de stockage
this->m_pBufferPos = NULL; // Pointeur sur le prochain caratère à ecrire
this->m_pBufferPosMax = NULL; // Valeur maxi du pointeur
this->m_iBufferSize = 0; // Taille allouée au tampon
this->m_iValueSize = 0; // Taille de la valeur contenue
// Mise à jour de la taille du tampon
this->increaseBuffer(p_iSize);
}
// Déstructeur
XCharBuffer::~XCharBuffer()
{
// Destruction du tampon si créé
if (this->m_pszBuffer)
if (!HeapFree(this->m_hHeapHandle, 0, this->m_pszBuffer))
{
;// Ya Erreur ! ;
}
}
/****************************************************************
// Redefini la taille de (p_size) caratère
bool XCharBuffer::setBufferSize(const unsigned int p_size)
{
return this->resizeBuffer(p_size);
}
// Ajuste la taille du tampon au contenu
bool XCharBuffer::pack()
{
return this->resizeBuffer(this->m_iValueSize);
}
// Retourne la taille de la chaine contenu (sans le \0)
unsigned int XCharBuffer::getValueSize()
{
return this->m_iValueSize;
}
// Retourne la taille du tampon
unsigned int XCharBuffer::getBufferSize()
{
return this->m_iBufferSize;
}
/****************************************************************
// Efface le contenu du tampon
void XCharBuffer::clear()
{
// Mise à 0 de tous les caractères
for (char* pChar = this->m_pszBuffer; pChar < this->m_pBufferPosMax; pChar++)
// Positionement sur le premier caractère
this->m_pBufferPos = this->m_pszBuffer;
// Réajustement de la taille de la valeur
this->m_iValueSize = 0;
}
// Ajoute une chaine
void XCharBuffer::append(const char* p_pszValue)
{
// Lecture du nombre de caractère à ajouter
unsigned int iSize = this->getLength(p_pszValue);
// Agrandissement du tampon
if (this->increaseBuffer(iSize))
{
// Copie de la nouvelle chaine
this->copyBuffer(p_pszValue, this->m_pBufferPos, iSize);
// Positionement sur le prochain caractère
this->m_pBufferPos += iSize;
// Mise à jour de la taille de la valeur
this->m_iValueSize += iSize;
}
}
// Ajoute une chaine
void XCharBuffer::append(const unsigned char* p_pszValue)
{
this->append((const char*)p_pszValue);
}
// Retourne le contenu (char*)
char* XCharBuffer::toCharArray()
{
return this->m_pszBuffer;
}
/*****************************************************************
*
*
// Crée ou agrandi le buffer si necessaire pour y stocker (p_iSize) nouveaux caractères
inline bool XCharBuffer::increaseBuffer(const unsigned int p_iSize)
{
// Si aucune taille nécessaire
if (p_iSize == 0)
return false;
// Si pas de mémoire allouée
if (!this->m_pBufferPos)
{
// Allocation pour le tampon (+ 1 pour le \0)
this->m_pszBuffer = (char*)HeapAlloc(this->m_hHeapHandle, HEAP_ZERO_MEMORY, p_iSize + 1);
if (!this->m_pszBuffer)
{
return false; // Ya Erreur
}
// Initialisation du tampon
this->m_pBufferPos = this->m_pszBuffer; // Positionement sur le premier caractère
this->m_pBufferPosMax = this->m_pBufferPos + p_iSize; // Définition du dernier caractère
this->m_iBufferSize = (unsigned int)p_iSize; // Définition de la taille du tampon
}
// Si mémoire déja allouée
else
{
// Calcul de l'espace restant
unsigned int iFreeSize = this->m_pBufferPosMax - this->m_pBufferPos;
// Si pas suffisement d'espace dans le tampon
if (iFreeSize < p_iSize)
{
// Calcul de l'espace nécessaire
unsigned int iRequiredSize = this->m_iBufferSize + (p_iSize - iFreeSize);
// Redimensionnement du tampon
if (!this->resizeBuffer(iRequiredSize))
{
return false; // Ya Erreur
}
}
}
return true;
}
// Redéfinie la taille du tampon existant à (p_iSize) caractères
inline bool XCharBuffer::resizeBuffer(const unsigned int p_iSize)
{
// Si pas de mémoire allouée
if (!this->m_pBufferPos)
return false; // Ya Erreur
// Reallocation du tampon (+1 pour le \0)
char* pNewBuffer = (char*)HeapReAlloc(this->m_hHeapHandle, HEAP_ZERO_MEMORY, this->m_pszBuffer, p_iSize + 1);
// Vérification si alloué
if (pNewBuffer)
{
this->m_pszBuffer = pNewBuffer; // Mise à jour de l'adresse du tampon
this->m_pBufferPos = this->m_pszBuffer + m_iBufferSize; // Positionement sur le prochain caractère
this->m_pBufferPosMax = this->m_pBufferPos + p_iSize; // Définition du dernier caractère
this->m_iBufferSize = p_iSize; // Définition de la taille du tampon
}
else
{
return false; // Ya Erreur
}
return true;
}
// Retourne la taille de la chaine sans le \0
inline unsigned int XCharBuffer::getLength(const char* p_pszValue)
{
unsigned int iSize = 0;
const char* pszPos = p_pszValue;
while(*pszPos++)
iSize++;
return iSize;
}
// Copie les (p_iSize) caractères du buffer (source) vers le buffer (target)
inline void XCharBuffer::copyBuffer(const char* p_pszSrcValue, char* p_pszTrgValue, unsigned int p_iSize)
{
const char* pSrc = p_pszSrcValue;
char* pTrg = p_pszTrgValue;
for (unsigned int i = 0; i < p_iSize; i++)
}
Conclusion :
Voici la procédure que j'utilise pour les test
En testant différentes tailles lors de l'initialisation (dans le constructeur)
il m'arrive que le return 0 du main() génére une exception avec le message suivant
Free Heap block 1345b0 modified at 1345e4 after it was freed
Je cherche mais je n'ai toujours pas compris pourkoi ??????
Je sais qu'avait la valeur 100, le code suivant termine en erreur
int main(int argc, char* argv[])
{
//XCharBuffer *poBuffer = new XCharBuffer(0);
XCharBuffer *poBuffer = new XCharBuffer(32);
poBuffer->append("toto");
std::cout << poBuffer->toCharArray() << " - "
<< (int)poBuffer->getValueSize() << " - "
<< (int)poBuffer->getBufferSize() << std::endl;
poBuffer->append(" et pis tata");
std::cout << poBuffer->toCharArray() << " - "
<< (int)poBuffer->getValueSize() << " - "
<< (int)poBuffer->getBufferSize() << std::endl;
poBuffer->pack();
std::cout << poBuffer->toCharArray() << " - "
<< (int)poBuffer->getValueSize() << " - "
<< (int)poBuffer->getBufferSize() << std::endl;
delete poBuffer;
return 0;
}
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.