Варадикт функции - PullRequest
       49

Варадикт функции

0 голосов
/ 29 апреля 2020

Как мне установить my_printf, чтобы он делал то, что printf ("% p") делает + без использования printf.

void my_printf(char * format, ...)
{
va_list ap;
va_start(ap, format);

if(!strcmp(format,"%p"))
  {
        void *address= va_arg (ap, void*);
        char *arr=malloc(sizeof(address));
        arr=address;
        arr[strlen(arr)]='\0';
        write(1,arr,strlen(arr));
  }
    va_end (ap);

 //it has to print an address in hexadecimal format.
}

1 Ответ

0 голосов
/ 29 апреля 2020

In:

char *arr=malloc(sizeof(address));
arr=address;

выделенный блок потерян, это утечка памяти

Чтобы сделать:

arr[strlen(arr)]='\0';

не имеет смысла, если вы можете использовать strlen, что означает, что нулевой символ уже присутствует. Но совсем не уверен, что у вас есть строка, поэтому вы не можете использовать strlen для этого указателя. Вы не знаете, можете ли вы изменить его по многим причинам, и на самом деле это бесполезно.

В

write(1,arr,strlen(arr));

снова предполагает вас иметь строку, которая может быть неправильной, и ваша цель состоит не в том, чтобы записать содержимое указанного значения, а в его адрес.


Способ сделать так:

#include <stdint.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h> /* for malloc use in main */

void my_printf(char * format, ...)
{
  va_list ap;
  va_start(ap, format);

  if (!strcmp(format,"%p"))
  {
    void * address= va_arg(ap, void*);
    uintptr_t u = (uintptr_t) address;

    if (u == 0)
      fputs("(nil)", stdout);
    else {
      char s[2 * ((sizeof(u) * CHAR_BIT + 7) / 8) + 3];
      int i = sizeof(s) - 1;

      s[i] = 0;

      do {
        s[--i] = ((u & 0xf) < 10) ? ('0' + (u & 0xf)) : ('a' + (u & 0xf) - 10);
        u >>= 4;
      } while(u);

      s[--i] = 'x'; /* can also putchar('0') */
      s[--i] = '0'; /* can also putchar('x') */

      fputs(s+i, stdout);
    }

    /* check */
    printf("\n%p\n", address);
  }
  va_end (ap);
}

int main()
{
  void * p = malloc(1);

  my_printf("%p", 0);
  my_printf("%p", &main);       
  my_printf("%p", &p);
  my_printf("%p", p);

  free(p);

  return 0;
}

Компиляция и выполнение:

pi@raspberrypi:/tmp $ gcc -Wall p.c
pi@raspberrypi:/tmp $ ./a.out
(nil) 
(nil)
0x106b8 
0x106b8
0xbec2d26c 
0xbec2d26c
0x10b1558 
0x10b1558
pi@raspberrypi:/tmp $ 

Обратите внимание, что ваш printf очень ограничен и поддерживает только простой формат %p

...