Правильный способ инициализации неподписанного символа * - PullRequest
15 голосов
/ 02 февраля 2011

Как правильно инициализировать unsigned char*? В настоящее время я делаю это:

unsigned char* tempBuffer;
tempBuffer = "";

Или я должен использовать memset(tempBuffer, 0, sizeof(tempBuffer));?

Ответы [ 7 ]

19 голосов
/ 02 февраля 2011

Чтобы "правильно" инициализировать указатель (unsigned char *, как в вашем примере), вам нужно сделать просто

unsigned char *tempBuffer = NULL;

Если вы хотите инициализировать массив unsigned char s, вы можете сделать одно из следующих действий:

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

или

unsigned char tempBuffer[1024] = {};

Я бы также рекомендовал взглянуть на std::vector<unsigned char>, который вы можете инициализировать так:

std::vector<unsigned char> tempBuffer(1024, 0);
9 голосов
/ 02 февраля 2011

Второй метод оставит вас с нулевым указателем.Обратите внимание, что вы не объявляете здесь место для буфера, вы объявляете указатель на буфер, который должен быть создан в другом месте.Если вы инициализируете его "", то указатель будет указывать на статический буфер с ровно одним байтом - нулевым терминатором.Если вам нужен буфер, в который вы можете записывать символы позже, используйте предложение массива Фреда или что-то вроде malloc.

5 голосов
/ 02 февраля 2011

Поскольку это указатель, вы либо хотите сначала инициализировать его в NULL, например:

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

или присвойте адрес переменной, например:

unsigned char c = 'c';

unsigned char* tempBuffer = &c;

EDIT: Если вы хотите назначить строку, это можно сделать следующим образом:

unsigned char myString [] = "This is my string";
unsigned char* tmpBuffer = &myString[0];
3 голосов
/ 02 февраля 2011

Если вам известен размер буфера во время компиляции:

unsigned char buffer[SIZE] = {0};

Для динамически распределяемых буферов (буферов, выделенных во время выполнения или в куче ):

1.Предпринимайте оператор new:

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

2.Многие решения «инициализировать» или заполнить простым значением:

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. Язык Cсторона обеспечивает выделение и инициализацию одним вызовом.
Однако , функция не вызывает конструкторы объекта:

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

Обратите внимание, что это также устанавливает все биты в буфере на ноль;у вас нет выбора в начальном значении.

2 голосов
/ 02 февраля 2011

Это зависит от того, чего вы хотите достичь (например, хотите ли вы когда-либо изменить строку). Смотрите, например http://c -faq.com / charstring / index.html для получения более подробной информации.

Обратите внимание, что если вы объявляете указатель на строковый литерал, он должен быть const, т.е.

const unsigned char *tempBuffer = "";
1 голос
/ 02 февраля 2011

Ответ зависит от того, для чего вы решили использовать неподписанный символ. Символ - это ничего , кроме небольшого целого числа, которое имеет размер 8 бит в 99% всех реализаций.

В C есть поддержка строк, которая хорошо сочетается с char, но это не ограничивает использование char для строк.


Правильный способ инициализации указателя зависит от 1) его области применения и 2) его предполагаемого использования.

Если указатель объявлен статическим и / или объявлен в области видимости файла, то ISO C / C ++ гарантирует, что он инициализирован в NULL. Пуристы стиля программирования все равно установили бы его в NULL, чтобы их стиль соответствовал локальным переменным области видимости, но теоретически это бессмысленно.

Что касается того, что инициализировать, чтобы ... установить его в NULL. Не устанавливайте его в «», потому что это выделит статический фиктивный байт, содержащий нулевое завершение, которое станет крошечной утечкой статической памяти, как только указатель будет назначен чему-то другому.

Кто-то может спросить, зачем вам вообще нужно инициализировать его вообще. Просто установите его на что-то действительное, прежде чем использовать его. Если вы беспокоитесь об использовании указателя перед тем, как дать ему правильное значение, вы должны найти подходящий статический анализатор для поиска таких простых ошибок. Даже большинство компиляторов поймают эту ошибку и выдадут вам предупреждение.

1 голос
/ 02 февраля 2011

Если план состоит в том, чтобы он был буфером, и вы хотите переместить его позже, чтобы указать на что-то, то инициализируйте его значением NULL, пока он действительно не укажет куда-то, куда вы хотите записать, а не пустой строкой.

unsigned char * tempBuffer = NULL;
std::vector< unsigned char > realBuffer( 1024 );
tempBuffer = &realBuffer[0]; // now it really points to writable memory
memcpy( tempBuffer, someStuff, someSizeThatFits );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...