Почему я получаю это нарушение прав доступа?

Я, вероятно, делаю что-то глупое здесь, но я давно не работал на С++, и по какой-то причине я продолжаю получать нарушение прав доступа при вызове sprintf. В любом случае, вот код, который я использую:

char *value, *result;
int len;
result = "";
mgr.GetObjValue(0, value, len);

for (int i = 0; i < len; i++) 
{
  sprintf(result, "%s %X", result, value[i]);
}

printf("ObjVal: %s\n\n", result);

если кому-то интересно, что делает GetObjValue, он просто извлекает значение объекта SNMP из API, который я использую. Вот его декларация:

int SNMPMgr::GetObjValue(int iObjIndex, char *&lpObjValue, int &lenObjValue);

Любая помощь приветствуется


person Brandon    schedule 29.11.2012    source источник
comment
На самом деле место вообще не резервируется, result указывает на статическую память…   -  person filmor    schedule 29.11.2012
comment
@chris - на самом деле даже не один символ - результат - просто оборванный указатель.   -  person user93353    schedule 29.11.2012
comment
@filmor, ты прав. Я не думаю прямо. Перезапись даже этого одного символа — это плохо.   -  person chris    schedule 29.11.2012
comment
@chris - какой персонаж?   -  person user93353    schedule 29.11.2012
comment
Указатель указывает на строковый литерал, его нельзя изменить, его поведение не определено.   -  person Alok Save    schedule 29.11.2012
comment
@Крис - ах! Я не видел result = "" - Во всяком случае, это буквальный, как говорит Алс - это приводит к неопределенному поведению для его изменения.   -  person user93353    schedule 29.11.2012


Ответы (2)


sprintf не выделяет память. Он ожидает получить указатель на доступный для записи буфер достаточной длины для хранения данных.

char *result;

На данный момент содержимое результата не определено.

result = "";

В этот момент результат указывает на статическую, доступную только для чтения строку из 1 байта (конечный нуль).

sprintf(result, "%s %X", result, value[i]);

В этот момент вы только что попытались записать произвольно длинную строку в доступную только для чтения область размера 1. Упс.

Вместо этого сделайте что-то вроде этого:

char result[1024];
sprintf(result, "%s %X", result, value[i]);

Обратите внимание, что при использовании snprintf или sprintf_s, чтобы избежать даже возможности перезаписи вашего буфера, вероятно, является хорошей идеей. (Поскольку вы используете C++, вы также можете легко использовать одну из библиотек форматирования C++, например Boost.Format, который выделяет память за вас, но это совсем другая тема.)

person Josh Kelley    schedule 29.11.2012
comment
Даже тогда в цикле for каждая итерация будет перезаписывать последнюю итерацию. - person user93353; 29.11.2012
comment
Спасибо, как я уже сказал, я был уверен, что делаю что-то глупое, и, конечно же, не выделять память — это довольно плохо. Но спасибо за подробный ответ. - person Brandon; 29.11.2012

Проблема здесь: char* result = "";

Вы пытаетесь напечатать постоянную строку (пустую строку). Из документации для sprintf относительно первого параметра:

Указатель на буфер, в котором хранится результирующая C-строка. Буфер должен быть достаточно большим, чтобы вместить результирующую строку.

Вам нужно выделить буфер для печати.

person Joe Bane    schedule 29.11.2012