我正在编写一个简单的程序,该程序将获取给定变量的内存地址高达64位(unsigned long)。目前这是我的代码,但由于某种原因,编译器向我抛出警告,说我的方法返回了一个局部变量的地址,而这正是我想要的。
int main(int argc, char *argv[])
{
char* one = argv[1];
long memaddress = address(one);
}
uint64_t address( char * strin)
{
return (uint64_t) &strin;
}
我该如何减轻这个警告,什么可能导致这个警告出现?
您可以想象函数定义和它的调用
long address = address(one);
//...
uint64_t address( char * strin)
{
return (uint64_t) &strin;
}
下面的方法
long address = address(one);
//...
uint64_t address( void )
{
char * strin = one;
return (uint64_t) &strin;
}
如您所见,变量strin
是函数的局部变量。它将在退出函数后被销毁。因此,退出函数后其地址将无效。编译器会警告你这个
为了避免警告,您至少可以按照以下方式编写函数
uint64_t address( char ** strin)
{
return (uint64_t) &*strin;
}
并将其命名为
long address = address(&one);
参数strin
是address
函数的局部参数,当address
返回时不存在,导致main
函数中的指针值无效,因此出现警告。
strin
是一个在address
中按值传递的指针。
你实际上是在尝试返回它的地址,尽管转换成不同的类型。
但是一旦函数退出,strin
的地址将不再有效,并且您的友好编译器会警告您。
解决方案是使用void*
作为地址,而不是为完全不同的东西设计的某些类型
当您将变量传递给函数时,它会创建该变量的副本,并将其作为局部变量传递给您调用的函数。如果您返回这个变量的地址,您将获得从返回的函数的局部变量的位置。也就是说,在本例中,您将不会获得one
变量的位置,而是strin
变量的位置。