确定指针是否有效 [英] Determining Whether Pointer is Valid

查看:135
本文介绍了确定指针是否有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的观察是,如果 free(ptr)被调用,其中 ptr 不是有效的指针系统分配的内存,发生访问冲突。让我们说,我这样调用 free

  LPVOID ptr = LPVOID)0x12345678; 
free(ptr);

这绝对会导致访问冲突。是否有一种方法来测试 ptr 指向的内存位置是否是有效的系统分配内存?



在我看来,Windows操作系统内核的内存管理部分必须知道什么内存已分配和什么内存保留分配。否则,如何知道是否有足够的内存来满足给定的请求? (修辞)也就是说,似乎合理的结论是,必须有一个函数(或一组函数),允许用户确定指针是否是有效的系统分配的内存。也许微软没有公开这些功能。如果Microsoft没有提供这样的API,我只能假定它是一个故意和具体的原因。

情况报告



虽然知道内存指针是否有效在许多情况下可能是有用的,这是我的特殊情况:



我正在写一个新的驱动程序的硬件,用于替换通过USB连接到PC的现有硬件。我的任务是编写新的驱动程序,使得对当前驱动程序的现有API的调用将继续在使用它的PC应用程序中工作。因此,对现有应用程序的唯一必需的更改是在启动时加载相应的驱动程序DLL。这里的问题是,现有驱动程序使用回调来向应用程序发送接收到的串行消息;包含消息的分配存储器的指针通过回调从驱动程序传递到应用程序。然后应用程序负责调用另一个驱动程序API以通过将相同的指针从应用程序传回给驱动程序来释放内存。在这种情况下,第二个API无法确定应用程序是否实际传回了指向有效内存的指针。

解决方案

解决你的具体问题,我不认为你不必担心检查指针。如果应用程序将您的DLL传递的地址无效,则表示应用程序中的内存管理问题 。无论您如何编写驱动程序,您都无法修复真正的错误。



为帮助应用程序开发人员调试其问题,您可以添加麻烦号码到您返回到应用程序的对象。当你的库被调用释放一个对象,检查号码,如果它不在那里,打印调试警告,不要释放它!即:

  #define DATA_MAGIC 0x12345678 
struct data {
int foo; / *实际对象数据。 * /
int magic; / *内存调试的幻数。 * /
};

struct data * api_recv_data(){
struct data * d = malloc(sizeof(* d));
d-> foo = whatever;
d-> magic = DATA_MAGIC;
return d;
}

void api_free_data(struct data * d){
if(d-> magic == DATA_MAGIC){
d-> magic = 0;
免费(d);
} else {
fprintf(stderr,api_free_data()要求释放无效数据%p \\\
,d);
}
}

这只是一种调试技术。 / strong>如果应用程序没有内存错误,这将正确工作。如果应用程序确实有问题,这可能会 提醒开发人员错误。它只有工作,因为你的实际问题是更多的约束,你的初始问题表示。


It has been my observation that if free( ptr ) is called where ptr is not a valid pointer to system-allocated memory, an access violation occurs. Let's say that I call free like this:

LPVOID ptr = (LPVOID)0x12345678;
free( ptr );

This will most definitely cause an access violation. Is there a way to test that the memory location pointed to by ptr is valid system-allocated memory?

It seems to me that the the memory management part of the Windows OS kernel must know what memory has been allocated and what memory remains for allocation. Otherwise, how could it know if enough memory remains to satisfy a given request? (rhetorical) That said, it seems reasonable to conclude that there must be a function (or set of functions) that would allow a user to determine if a pointer is valid system-allocated memory. Perhaps Microsoft has not made these functions public. If Microsoft has not provided such an API, I can only presume that it was for an intentional and specific reason. Would providing such a hook into the system prose a significant threat to system security?

Situation Report

Although knowing whether a memory pointer is valid could be useful in many scenarios, this is my particular situation:

I am writing a driver for a new piece of hardware that is to replace an existing piece of hardware that connects to the PC via USB. My mandate is to write the new driver such that calls to the existing API for the current driver will continue to work in the PC applications in which it is used. Thus the only required changes to existing applications is to load the appropriate driver DLL(s) at startup. The problem here is that the existing driver uses a callback to send received serial messages to the application; a pointer to allocated memory containing the message is passed from the driver to the application via the callback. It is then the responsibility of the application to call another driver API to free the memory by passing back the same pointer from the application to the driver. In this scenario the second API has no way to determine if the application has actually passed back a pointer to valid memory.

解决方案

To address your specific concern, I don't think you have to worry about checking the pointer. If the application passes your DLL an invalid address, it represents a memory management problem in the application. No matter how you code your driver, you can't fix the real bug.

To help the application developers debug their problem, you could add a magic number to the object you return to the application. When the your library is called to free an object, check for the number, and if it isn't there, print a debug warning and don't free it! I.e.:

#define DATA_MAGIC 0x12345678
struct data {
    int foo;    /* The actual object data. */
    int magic;  /* Magic number for memory debugging. */
};

struct data *api_recv_data() {
    struct data *d = malloc(sizeof(*d));
    d->foo = whatever;
    d->magic = DATA_MAGIC;
    return d;
}

void api_free_data(struct data *d) {
    if (d->magic == DATA_MAGIC) {
        d->magic = 0;
        free(d);
    } else {
        fprintf(stderr, "api_free_data() asked to free invalid data %p\n", d);
    }
}

This is only a debugging technique. This will work the correctly if the application has no memory errors. If the application does have problems, this will probably alert the developer to the mistake. It only works because you're actual problem is much more constrained that your initial question indicates.

这篇关于确定指针是否有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆