确定const char *是字符串文字还是变量

时间:2013-03-26 14:49:26

标签: c++ winapi string-literals

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

我正在尝试修复一些代码中的错误,这些代码填充了IsBadWritePtr调用,如果参数是常量字面值,则抛出访问冲突异常。

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

4 个答案:

答案 0 :(得分: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 

请注意,他们并未完全检测文字非文字,而是其他一些功能。 const char* p = createANewString(); f(p);将解析为f(const char*)const char x[] = { 'A', 'b', 'c', '\0' };将解析为模板。它们都不是文字,但您可能不想修改它们。

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

这一切的前提是主函数不应该将参数作为const char*,如果它在内部修改它,并且您面临的问题是因为为了向后兼容,您的编译器允许调用使用文字...

获取指向非const的指针的函数

答案 1 :(得分:1)

我认为没有办法在不使用某些hackery的情况下检测到这种情况。
由于接口采用const char *函数的职责是不修改传递的字符串。您需要修改实现,因为它完全不正确。

答案 2 :(得分:0)

VirtualQuery可用于检测地址是可写,只读还是不可访问。检查返回的State结构的ProtectMEMORY_BASIC_INFORMATION成员,以查看内存是否可访问且是否具有所需的访问权限。

答案 3 :(得分:0)

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

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