web-dev-qa-db-fra.com

Méthode appropriée pour initialiser un caractère non signé *

Quelle est la bonne façon d'initialiser unsigned char*? Je fais actuellement ceci:

unsigned char* tempBuffer;
tempBuffer = "";

Ou devrais-je utiliser memset(tempBuffer, 0, sizeof(tempBuffer));?

16
Brian

La deuxième méthode vous laissera un pointeur nul. Notez que vous ne déclarez aucun espace pour un tampon ici, vous déclarez un pointeur à un tampon qui doit être créé ailleurs. Si vous l'initialisez sur "", qui fera pointer le pointeur vers un tampon statique avec exactement un octet - le terminateur nul. Si vous voulez un tampon dans lequel vous pourrez écrire des caractères plus tard, utilisez la suggestion de tableau de Fred ou quelque chose comme malloc.

9
Karl Bielefeldt

Pour initialiser "correctement" un pointeur (unsigned char * comme dans votre exemple), vous devez faire simplement

unsigned char *tempBuffer = NULL;

Si vous souhaitez initialiser un tableau de unsigned chars, vous pouvez effectuer l'une des opérations suivantes:

unsigned char *tempBuffer = new unsigned char[1024]();
// and do not forget to delete it later
delete[] tempBuffer;

ou

unsigned char tempBuffer[1024] = {};

Je recommanderais également de jeter un œil à std::vector<unsigned char>, que vous pouvez initialiser comme ceci:

std::vector<unsigned char> tempBuffer(1024, 0);
21
Dmitry

Comme il s'agit d'un pointeur, vous devez d'abord l'initialiser à NULL comme ceci:

unsigned char* tempBuffer = NULL;
unsigned char* tempBuffer = 0;

ou attribuer une adresse de variable, comme ceci:

unsigned char c = 'c';

unsigned char* tempBuffer = &c;

EDIT: Si vous souhaitez affecter une chaîne, cela peut être fait comme suit:

unsigned char myString [] = "This is my string";
unsigned char* tmpBuffer = &myString[0];
6
Kerri Brown

Si vous connaissez la taille du tampon au moment de la compilation:

unsigned char buffer[SIZE] = {0};

Pour les tampons alloués dynamiquement (tampons alloués pendant l'exécution ou sur le tas ):

1.Préférer l'opérateur new:

unsigned char * buffer = 0;  // Pointer to a buffer, buffer not allocated.
buffer = new unsigned char [runtime_size];

2. De nombreuses solutions pour "initialiser" ou remplir avec une valeur simple:

std::fill(buffer, buffer + runtime_size, 0); // Prefer to use STL
memset(buffer, 0, runtime_size);
for (i = 0; i < runtime_size; ++i) *buffer++ = 0;  // Using a loop

3.Le côté langage C fournit l'allocation et l'initialisation avec un seul appel.
Cependant, la fonction n'appelle pas les constructeurs de l'objet:

buffer = calloc(runtime_size, sizeof(unsigned char))

Notez que cela met également tous les bits du tampon à zéro; vous n'avez pas le choix dans la valeur initiale.

4
Thomas Matthews

Cela dépend de ce que vous voulez réaliser (par exemple, voulez-vous jamais modifier la chaîne). Voir par ex. http://c-faq.com/charstring/index.html pour plus de détails.

Notez que si vous déclarez un pointeur sur un littéral de chaîne, il doit être const, c'est-à-dire:

const unsigned char *tempBuffer = "";
2
Oliver Charlesworth

Si le plan est qu'il s'agit d'un tampon et que vous souhaitiez le déplacer plus tard pour pointer vers quelque chose, initialisez-le à NULL jusqu'à ce qu'il pointe vraiment quelque part vers lequel vous voulez écrire, pas une chaîne vide.

unsigned char * tempBuffer = NULL;
std::vector< unsigned char > realBuffer( 1024 );
tempBuffer = &realBuffer[0]; // now it really points to writable memory
memcpy( tempBuffer, someStuff, someSizeThatFits );
1
CashCow

La réponse dépend de ce que vous avez l'intention d'utiliser pour le caractère non signé. Un caractère est rien sinon mais un petit entier, qui est de taille 8 bits sur 99% de toutes les implémentations.

C a un support de chaîne qui correspond bien à char, mais cela ne limite pas l'utilisation de char aux chaînes.


La bonne façon d'initialiser un pointeur dépend 1) de sa portée et 2) de son utilisation prévue.

Si le pointeur est déclaré statique et/ou déclaré à la portée du fichier, ISO C/C++ garantit qu'il est initialisé à NULL. Les puristes du style de programmation le définiraient toujours sur NULL pour garder leur style cohérent avec les variables de portée locales, mais théoriquement, cela est inutile.

Quant à quoi l'initialiser ... définissez-le sur NULL. Ne le définissez pas sur "", car cela allouera un octet factice statique contenant une terminaison nulle, qui deviendra une toute petite fuite de mémoire statique dès que le pointeur est affecté à autre chose.

On peut se demander pourquoi vous devez l'initialiser à quoi que ce soit en premier lieu. Réglez-le simplement sur quelque chose de valide avant de l'utiliser. Si vous vous inquiétez d'utiliser un pointeur avant de lui donner une valeur valide, vous devriez obtenir un analyseur statique approprié pour trouver de tels bogues simples. Même la plupart des compilateurs attraperont ce bogue et vous avertiront.

1
Lundin