2013-03-26 6 views
2

Есть ли какой-либо простой метод для обнаружения, если параметр, переданный функции (const char * argument), был константным литералом или переменной?Решите, если const char * является строковым литералом или переменной

Я пытаюсь исправить ошибки в некотором коде, который заполняется вызовами IsBadWritePtr, которые вызывают исключения нарушения доступа, если параметр был постоянным литералом.

Это была ужасная глупость дизайна, но теперь мне не разрешено изменять неудобное поведение.

+0

Я не понимаю, почему это имеет значение. Вы можете обрабатывать указатель на первый элемент массива 'const char' точно так же, независимо от того, был ли он создан строковым литералом или нет. –

+0

@sftrabbit Я думаю, есть две потенциальные проблемы: это строка с нулевым завершением? И это указатель на один символ? – juanchopanza

+1

@MM: Скажите, что ???? Литерал * не * временный. Это * наименее * временный тип объекта, так как его продолжительность - это вся программа. –

ответ

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 

Обратите внимание, что они не совсем обнаружить буквальным vs. не литерал, а скорее некоторые другие функции. const char* p = createANewString(); f(p); будет разрешен к f(const char*), и const char x[] = { 'A', 'b', 'c', '\0' }; разрешит шаблон. Ни один из них не является литералами, но вы, вероятно, тоже не хотите изменять.

Как только вы сделаете это изменение, должно быть легко узнать, где вызывается каждая из перегрузок.

Это все работает на том основании, что основная функция не должна принимать аргумент как const char*, если он изменяет его внутренне и что проблема, с которой вы сталкиваетесь, заключается в том, что для обратной совместимости ваш компилятор разрешает вызов функции, которая принимает указатель на не-const с литералом ...

1

Я не думаю, что есть способ обнаружить это, по крайней мере, без использования какого-либо хакера.
Поскольку интерфейс принимает const char *, ответственность за эту функцию состоит в том, чтобы в любом случае не изменять переданную строку. Вам нужно изменить реализацию, потому что она просто неверна.

0

VirtualQuery может использоваться для обнаружения, является ли адрес доступным для записи, недоступным для чтения или недоступным. Изучите элементы State и Protect возвращенной структуры MEMORY_BASIC_INFORMATION, чтобы узнать, доступна ли память и какой доступ вам нужен.