2015-10-26 2 views
-1

Я знаю, что есть тонны эти и это, вероятно, простой вопрос, но я не могу понять это :(MemSet не обнуление обугленного указателя

char * char_buffer = (char *) malloc(64); 
printf("%x\n", char_buffer); 
memset(char_buffer, 
     0, 
     64); 

printf("%x\n", char_buffer); 

Выход:

50000910 
50000910 

Почему не char_buffer zero'd? Может кто-нибудь объяснить, что происходит?

+0

FYI: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Barmar

ответ

2

Вы смущены о разнице между указателем и пространством, и указал на.

Ваш код не имеет нулевого указателя. Он нулевает указанное пространство. Функция memset ведет себя так. На самом деле вы не захотите обнулить указатель, так как тогда он больше не будет указывать на выделенную вами память.

Ваш оператор printf пытается напечатать значение указателя, на которое указывает адрес пространства. Не указывается содержимое пространства.

Фактически оператор printf вызывает неопределенное поведение, поскольку вы не определили спецификаторы формата. Ваш компилятор должен был предупредить об этом.

Вот некоторые правильный код:

printf("The buffer's address is %p\n", char_buffer); 
printf("The buffer contains: %02X %02X %02X ...\n", 
    (unsigned char)char_buffer[0], 
    (unsigned char)char_buffer[1], 
    (unsigned char)char_buffer[2]); 

Чтобы использовать %X спецификатор вы должны пройти неотрицательные значения, поэтому бросок необходимо. Вместо этого вы можете объявить буфер как unsigned char *, и в этом случае приведение не требуется.

+0

Я думаю, вы должны использовать% d с unsigned char, http://stackoverflow.com/questions/27547377/format-specifier-for-unsigned-char –

+0

@Giorgi конечно, если вы хотите напечатать в базе 10 ... см. ответ «mafso», поясняющий, что безопасно использовать '% d','% u' или '% x'. Стандарт C неясен в определении поведения этих спецификаторов. –

+0

о '% x' ... ну, указатель * * конвертируется в' int', поэтому я бы сказал, что это не * ub *, а * ib * (поведение, определяемое реализацией). Все, что может случиться, это получить переполнение целых чисел .... –

0

Вы распечатывания указатель, а не все значения буфера.

memset(p,v,n) записывает байт v в байт, на который указывают p и n-1 байт после него. Это не касается указателя p на всех (она передается по значению, как может это?)

1

Вы печатая адрес буфера, а не его содержимое. Содержание : ноль после memset(). Просто попробуйте:

printf("%d", char_buffer[0]); 

и увидеть ноль;)

+0

Вы должны бросить аргумент '% hhu' to '(unsigned char)' –

+0

не нужно строго, но будет чище. Это действительно не имеет значения для печати нулей. И, конечно же, вы могли бы избежать всего этого, используя '% d', в конце концов, он передается как' int' anyways .... –

+1

Это необходимо, потому что 'u' specifier ожидает значение без знака, но' char_buffer [0 ] 'может быть отрицательным значением –

0

Чтобы распечатать буфер, вам придется пройти через него. Я использую что-то вроде этого:

void printbuf(char *buf, int size) 
{ 
    int i = 0; 
    char b = 0; 
    for (i = 0; i < size; i++) { 
     if (i % 8 == 0) { 
      printf("\n%3d: ", i); 
     } 
     b = buf[i]; 
     printf("%2hhX ", b); 
    } 
} 
Смежные вопросы