2013-03-26 49 views
2

如果传递给函数的参数(const char * argument)是一个常量字面量或变量,是否有任何简单的方法检测?决定是否const char *是一个字符串文字或变量

我试图修复一些代码中的错误,这些代码中充满了IsBadWritePtr调用,如果参数是一个常量字面量,它会抛出访问冲突异常。

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

+0

我不明白为什么它应该重要。无论是否由字符串文字创建,您都可以将指向“const char”数组的第一个元素的指针完全相同。 – 2013-03-26 14:52:17

+0

@sftrabbit我猜有两个潜在的问题:它是一个空字符串?它是一个指向单个“char”的指针吗? – juanchopanza 2013-03-26 14:54:56

+1

@MM .:说什么?文字是*不是临时的。它是*最少的*临时类型的对象,因为它的寿命是整个程序。 – 2013-03-26 14:59:46

回答

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

我不认为有一种方法来检测,至少不使用一些hackery。
由于接口需要一个const char *该函数的责任是无论如何不修改传递的字符串。你需要修改实现,因为它是不正确的。

0

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