2

是否有任何简单的方法可以检测传递给函数的参数(const char *argument)是常量文字还是变量?

我正在尝试修复一些代码中的错误,这些代码充满了 IsBadWritePtr 调用,如果参数是常量文字,则会引发访问冲突异常。

这是一个可怕的设计愚蠢,但现在我不允许改变尴尬的行为。

4

4 回答 4

3

您可以添加一个更适合字符串文字的不同重载。这不是真正的科学,而只是启发式:

void f(const char* p); // potential literal
void f(char *p);       // pointer to non-const

另一个想法是利用文字实际上是数组

template <int N>
void f(const char (&_)[N]); // potential literal 

请注意,它们并没有完全检测到literalnot literal,而是检测到其他一些特性。const char* p = createANewString(); f(p);将解析为f(const char*)const char x[] = { 'A', 'b', 'c', '\0' };并将解析为模板。它们都不是literals,但您可能也不想修改。

一旦进行了更改,就应该很容易找出每个重载的调用位置。

这一切的前提是主函数不应该像const char*在内部修改它一样接受参数,并且您面临的问题是因为为了向后兼容,您的编译器允许调用一个函数,该函数需要一个指向非带有文字的 const...

于 2013-03-26T14:57:27.360 回答
1

我不认为有一种方法可以在不使用一些黑客的情况下检测到这一点。
由于接口承担const char *了函数的责任,因此无论如何都不修改传递的字符串。您需要修改实现,因为它根本不正确。

于 2013-03-26T14:53:31.753 回答
0

VirtualQuery可用于检测地址是可写、只读还是不可访问。检查返回结构的StateProtect成员MEMORY_BASIC_INFORMATION以查看内存是否可访问以及是否具有您需要的访问权限。

于 2013-03-26T16:56:34.007 回答
0

一种非常骇人听闻的方法是检查指针是否在 .rdata 段中。

在构建之后使用dumpbin /headers来检索 .rdata 部分的偏移量和长度,或者自己解析 PE 标头。自然,这是特定于工具链的,通常是个坏主意。此外,如果代码需要与 DLL 互操作,您必须检查几个可执行文件和几个 .rdata 段。

于 2020-04-10T03:30:23.730 回答