c - Input from command line using atoi function -
i have written small program check page alignment. program works fine when hardcode value of address variable in program itself, when try take them commandline using argc , argv values, output goes haphazard, value of uint64_t cannot recovered commandline using atoi function..?
normal code, 1 can see value of address being hardcoded program itself.
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int aligned(uint64_t addr, uint64_t pgsize){ 5 return ((uint64_t)addr % pgsize == 0); 6 } 7 8 int main(int argc, char*argv[]){ 9 uint32_t i; 10 uint64_t addr, size; 11 addr=0x1900000000; 12 size=0x100000000 ; 13 14 for(i=0;i<7;i++) 15 if(aligned(addr,size>>i)){ 16 printf("aligned %#lx\n",size>>i); 17 } 18 else 19 printf("not aligned %#lx\n",size>>i); 20 return 0; 21 }
output
[souravhimanshu] ./aligned aligned 0 aligned 0x80000000 aligned 0x40000000 aligned 0x20000000 aligned 0x10000000 aligned 0x8000000 aligned 0x4000000
code command line input
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 int aligned(uint64_t addr, uint64_t pgsize){ 5 return ((uint64_t)addr % pgsize == 0); 6 } 7 8 int main(int argc, char*argv[]){ 9 uint32_t i; 10 uint64_t addr, size; 11 if(argc<2){ 12 printf("usage ./chkalign <address>\n"); 13 exit(-1); 14 } 15 addr=atoi(argv[1]); 16 printf("%#lx",addr); 17 //addr=0x1900000000; 18 size=0x100000000 ; 19 20 for(i=0;i<7;i++) 21 if(aligned(addr,size>>i)){ 22 printf("aligned %#lx\n",size>>i); 23 } 24 else 25 printf("not aligned %#lx\n",size>>i); 26 return 0; 27 }
output (incorrect)
[sourav@himanshu] ./chkalign 0x924000000 0aligned 0 aligned 0x80000000 aligned 0x40000000 aligned 0x20000000 aligned 0x10000000 aligned 0x8000000 aligned 0x4000000
as can see value of addr when printed after atoi function shows 0.
kindly advise...
you did not specify platform, aware memory addresses not same size int
. atoi
returns int
, hence problem.
even long
may not large enough hold memory address (as in windows iirc). therefore should use strtoull
returning unsigned long long
guaranteed @ least 64 bits. use 0
base conversion, allowing addresses entered 0x80000000
on command line. more consistent , portable types: long
not 64 bits, should not printed "%lx"
in printf
.
also work on style. consistency helps avoid bugs.
here corrected version:
#include <stdint.h> #include <stdio.h> #include <stdlib.h> int aligned(uint64_t addr, uint64_t pgsize) { return (addr % pgsize) == 0; } int main(int argc, char *argv[]) { int i; uint64_t addr, size; if (argc < 2) { printf("usage: ./chkalign <address>\n"); exit(-1); } addr = strtoull(argv[1], null, 0); printf("address %#llx:\n", (unsigned long long)addr); //addr = 0x1900000000; size = 0x100000000; (i = 0; < 7; i++) { if (aligned(addr, size >> i)) { printf("aligned %#llx\n", (unsigned long long)size >> i); } else { printf("not aligned %#llx\n", (unsigned long long)size >> i); break; } } return 0; }
Comments
Post a Comment