微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

访问由空指针引用的内存

如何解决访问由空指针引用的内存

我正在研究 C++ 中的 void 指针,作为练习,我编写了以下代码

void* routine(void* number){

    int n = (int)number;
    int* np = (int*)number;

    cout<<"void pointer: "<<number<<endl; 
    cout<<"casted int pointer: "<<np<<endl; 
    cout<<"int pointer content: "<<*np<<endl; 


    return (void*)NULL;
}

int  main(){
    int num = 1;
    routine((void*)num);
}

这会在运行时中断,因为从 np 强制转换为 void* 的指针 int* 被取消引用。

我尝试将参数 number 作为空指针传递并在函数内取消引用它的值。 void 指针的算术运算是非法的,因此我尝试做的是将指针强制转换为 int* 并尝试取消引用该强制转换的副本。

我有点希望这行不通,但如果是这种情况,我也希望出现某种编译器错误,就像在没有 int* 强制转换的情况下进行此尝试一样。我有点期望它起作用的原因是,强制转换的指针保留了原始的 void 指针地址,这意味着在强制转换之后它看起来只是一个常规的内存地址,我认为没有理由通过常规取消引用无法访问它。 n 变量是引用值的副本,但仅此而已 - 我无法更改内存地址中的实际值。

这可以用空指针吗?我错过了什么?

解决方法

通常的&num

routine(&num);

任何对象指针都会隐式转换为 void*。在回调函数中,您必须将其转换回正确的指针类型(使用 static_cast 而不是 C 风格的强制转换,这将防止您不小心将包含地址的指针与不是内存地址的整数值混淆) .

void* routine( void* user_ptr )
{
    int* np = static_cast<int*>(user_ptr);

不是对象指针的其他指针不会隐式转换为 void*,包括函数指针和指向成员的指针。添加强制转换将迫使编译器做错误的事情并对此保持沉默,但是(除了 dlsym() 的返回值或其 Windows 等效值 GetProcAddress())混合 {{ 1}} 无论如何都使用这些其他指针变体。

,
void* routine(void* number){

    int n = (int)number;
    int* np = (int*)number;

    cout<<"void pointer: "<<number<<endl; 
    cout<<"casted int pointer: "<<np<<endl; 
    cout<<"int pointer content: "<<*np<<endl; 


    return (void*)NULL;
}


int  main(){
    int num = 1;
    int* num_p = &num;
    routine((void*)num_p);
}

在传递之前指向 num 的地址可以解决问题。将整数转换为 空指针毫无意义。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。