检查一个指针是否合法,可访问

13 篇文章 0 订阅
文章介绍了如何使用LinuxAPI中的msync函数来检测一个指针是否指向有效的内存地址,而不考虑该内存是否已被分配。通过调用msync对包含指针的页面进行同步,如果返回0则表示指针合法,否则可能无效或引发错误。这种方法适用于debug和内存管理验证。
摘要由CSDN通过智能技术生成

主题

检测一个指针是否合法

注意: 这里只是检测一个指针是否可以访问, 不报错.
即对应地址在虚拟地址空间中, 有对应的页与物理地址对应;
并不能说明其已经被malloc了。

核心

参考链接

https://renatocunha.com/2015/12/msync-pointer-validity/
https://man7.org/linux/man-pages/man3/msync.3p.html

linux api

#include <sys/mman.h>
int msync(void *addr, size_t len, int flags);

说明
addr为起始地址, 长度为len的内存数据, 按照flags的方式同步到永久存储介质中(一般是磁盘);

成功返回0, 失败返回-1 + errno;

缓存到磁盘的同步

cpu cache刷新到存储介质中: cpu cache ==> memory ==> disk; cache的刷新会强制执行mesi, 将其他core的内容invalidate; 这一步可选;

内存类型

一般是map_public类型, 不过这里检测可以用于map_private类型; 可能不会写入存储介质; 这里也仅仅是检查debug的手段;

案例

核心代码

#include <sys/mman.h>
#include <stdbool.h>
#include <unistd.h>

bool is_pointer_valid(void *p) {
    /* get the page size */
    size_t page_size = sysconf(_SC_PAGESIZE);
    /* find the address of the page that contains p */
    void *base = (void *)((((size_t)p) / page_size) * page_size);
    /* call msync, if it returns non-zero, return false */
    return msync(base, page_size, MS_ASYNC) == 0;
}

候选返回值判断

int ret = msync(base, page_size, MS_ASYNC) != -1;
return ret ? ret : errno != ENOMEM;

完整案例

#include <sys/mman.h>
#include <stdbool.h>
#include <unistd.h>

bool is_pointer_valid(void *p) {
    /* get the page size */
    size_t page_size = sysconf(_SC_PAGESIZE);
    /* find the address of the page that contains p */
    void *base = (void *)((((size_t)p) / page_size) * page_size);
    /* call msync, if it returns non-zero, return false */
    return msync(base, page_size, MS_ASYNC) == 0;
}


#include <stdio.h>
int main() {
        void* null = reinterpret_cast<void*>(0x05050505);
        auto ret = is_pointer_valid(null);
        printf("addr = %p, valid : %s \n", null, ret ? "True" : "False");

        null = reinterpret_cast<void*>(&main);
        ret = is_pointer_valid(null);
        printf("addr = %p, valid : %s \n", null, ret ? "True" : "False");

        return 0;
}

执行输出

$ ./a.out
addr = 0x5050505, valid : False
addr = 0x558a70489729, valid : True
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值