2010-10-25 4 views
0

Mon programme se bloque par intermittence lorsqu'il essaie de copier un tableau de caractères qui n'est pas terminé par un terminateur NULL ('\ 0').Comment empêcher la copie d'une chaîne de pointeur sauvage

class CMenuButton { 
    TCHAR m_szNode[32]; 
    CMenuButton() { 
    memset(m_szNode, '\0', sizeof(m_szNode)); 
    } 
}; 
int main() { 
    .... 
    CString szTemp = ((CMenuButton*)pButton)->m_szNode; // sometime it crashes here 
    ... 
    return 0; 
} 

Je me doutais bien que quelqu'un n'a pas copié le caractère bien fini par « \ 0 », et il a fini comme:

  Stack 
m_szNode $%#^&!&!&!*@*#&!(*@(!*@@&#&*&@@!^&*&#(*[email protected]*((*&*SDFKJSHDF*(&(*&(()(** 

Pouvez-vous me dire ce qui se passe et que dois-je faire pour empêcher la copie du pointeur sauvage? L'aide sera très appréciée!

Je suppose que je suis incapable de vérifier si le tableau de caractères est NULL avant de copier ...

+0

Nous avons besoin de plus d'informations, telles que la façon dont pButton est créé, et ce qui arrive à ce pointeur entre sa création et la ligne de code que vous avez fournie ici. –

Répondre

3

Je soupçonne que votre vrai problème pourrait être que pButton est un mauvais pointeur, afin de vérifier que le premier. La seule façon d'être sûr à 100% qu'un pointeur est correct, et de pointer vers un objet correctement dimensionné/alloué, est de ne jamais utiliser de pointeurs que vous n'avez pas créés, et n'accepterez jamais les pointeurs. Au lieu de cela, vous utiliseriez des cookies et rechercheriez votre pointeur dans une sorte de cookie -> recherche de pointeur (comme une table de hachage). Fondamentalement, ne faites pas confiance à l'entrée de l'utilisateur. Si vous êtes plus soucieux de trouver des bogues, et moins de sécurité à 100% contre des attaques de type buffer overrun, etc., vous pouvez adopter une approche moins agressive. Dans vos signatures de fonction, où vous prenez actuellement des pointeurs vers des tableaux, ajoutez un paramètre de taille. .: par exemple

void someFunction(char* someString); 

Devient

void someFunction(char* someString, size_t size_of_buffer); 

En outre, la force la fin des tableaux/chaînes dans vos fonctions. Si vous atteignez la fin, et qu'il n'est pas terminé par un caractère nul, tronquez-le. Faites en sorte que vous puissiez fournir la taille du tampon lorsque vous les appelez, plutôt que d'appeler strlen (ou équivalent) sur tous vos tableaux avant de les appeler.

Ceci est similaire à l'approche adoptée par les «fonctions de chaîne de sécurité» qui ont été créées par Microsoft (dont certaines ont été proposées pour la normalisation). Je ne sais pas si cela est le lien parfait, mais vous pouvez google pour des liens supplémentaires:

http://msdn.microsoft.com/en-us/library/ff565508(VS.85).aspx

+0

Merci. Il est confirmé que pButton a été supprimé quelque part ... Ce n'est pas dû au tableau de caractères de taille fixe. – wengseng

2

Il y a deux possibilités:

  1. pButton ne pointe pas à un CMenuButton comme vous pensez qu'elle et la distribution provoque un comportement indéfini.
  2. Le code qui définit m_szNode est incorrect, dépassant la taille donnée de 32 caractères.

Puisque vous ne nous avez pas montré un morceau de code, il est difficile de voir ce qui ne va pas. Votre initialisation de m_szNode semble correcte.

Y a-t-il une raison quelconque pour laquelle vous n'avez pas choisi de CString pour m_szNode?

+0

+1 pour (aussi) frapper le clou sur la tête pour le vrai problème, plutôt que de suivre le trou de lapin du reste des questions qu'il a posées :) –

0

Mon approche serait de faire m_szNode un membre privé dans CMenuButton, et explicitement NULL - le terminer dans la méthode de mutateur.

class CMenuButton { 
    private: 
    TCHAR m_szNode[32]; 

    public: 
    void set_szNode(TCHAR x) { 
     // set m_szNode appropriately 
     m_szNode[ 31 ] = 0; 
    } 
};