stdarg.h头文件中va_arg的使用(关于类型获取)

简介:此博客用于简单分析va_arg函数完成特定类型获取后指针移动的问题(针对int型参数i= -2,147,483,648获取后,指针偏移发生的错误)。

 

 我在使用stdarg.h头文件模拟实现printf函数时遇见这样的情况:

 使用va_arg对函数可变参数进行特定类型获取后,va_arg函数再次读取时发生了关于地址访问的相关错误,如下述代码。

int printf(const char *fmt, ...) {
  const char *fm=fmt;
 int n=0;

  va_list ap;
  va_start(ap,fmt);

  //-2147483648
  char buf[10];
  for(int i=0;i<10;i++){
    buf[i]='\0';
  }

  while(*fm!='\0')
  {
    if(*fm=='%')
    {
      fm++;
      switch(*fm)
      {
        case 'd':{ 


        int i = va_arg(ap,int);
        int index=0;
        if (i<0)
        {
          putch('-');
        }
        for(int j=0;j<10;j++)
        {
          buf[j]=i%10>0 ? i%10 : 0-(i%10);
          i=i/10;
          if(i==0){index=j;break;}
        }
        for(int j=index;j>=0;j--)
        {     
          putch(buf[j]+48);
          if(buf[j]=='\0'){break;}
        }
        for(int i=0;i<10;i++){
          buf[i]='\0';
        }
        fm++;n++;
        break;}

        case 's':{
        char const *to_cpy = va_arg(ap,char*);
        putstr(to_cpy);
        fm++;n++;      
        break;}
      }
    } 
    else
        {putch(*fm); fm++;}

  }
  va_end(ap);
  return n;
}

 

错误分析:上述代码中,va_arg函数获取了int型整数(4字节)之后,指针向后进行偏移。
     但是由于-2147483648数值存在了溢出,系统以八字节进行(对int进行扩展成longlong)存储,
     这是指针仅仅偏移了四个字节,因此没有到达下一个参数的地址,导致va_arg中取值异常。
简单修改:对-2147483648(即溢出)进行判断,在获取此数值之后va_arg再次进行一次int类型的获取(目的是让指针偏移,但不取值)。
     具体的————>if(i==-2147483648){va_arg(ap,int);}

 

posted @ 2024-01-18 19:19  Smith_count  阅读(71)  评论(0)    收藏  举报