нарушение прав доступа sprintf

У меня проблема со следующим кодом:

for(i = 0;(i - 1)< n;i++)
{
char* b;
sprintf(b, "%d", i);
}

Он компилируется нормально, но когда я его запускаю, он выдает печально известную ошибку «0XC0000005 Access Violation». Я пытался установить b в NULL, "", "0", 0 и кучу других вещей, но затем я получаю ошибку "0XC0000005 Access Violation" или "Expression: string != NULL. Любая помощь будет оценена по достоинству!


person user37875    schedule 07.12.2008    source источник
comment
См. stackoverflow.com/questions/346499/c-pointer-confusion# 346598   -  person jfs    schedule 07.12.2008


Ответы (5)


sprintf записывает данные в существующий буфер, который вы передаете ему в качестве первого параметра. В настоящее время вы вообще не указываете значение для b, что означает (IIRC в C) значение может быть любым. Если вы установите его в NULL или 0, sprintf попытается записать в память, начиная с адреса 0.

Вам нужно создать буфер соответствующего размера, чтобы sprintf мог писать в него. Например:

for(i = 0;(i - 1)< n;i++)
{
    char b[10];
    sprintf(b, "%d", i);
}

Будет ли это на самом деле то, как вы хотите выделить буфер, зависит, конечно, от того, что ваш реальный код хочет делать с результатами.

person Jon Skeet    schedule 07.12.2008

Хм... Ваш указатель на b содержит мусор, так как вы его не инициализировали и не выделили место. Springtf требует, чтобы вы выделили буферное пространство назначения...

Как минимум, вам нужно что-то вроде char b[50] или любого ожидаемого максимального размера, а не просто char*.

person Uri    schedule 07.12.2008

char* — это неинициализированный указатель на char или массив char. Вам нужно определить буфер char[10], иначе целевой адрес sprintf не определен.

person devio    schedule 07.12.2008

sprintf требует передать ему уже выделенный буфер символов, достаточно большой для хранения любого возможного результата. Это сильно подвержено переполнению буфера - вместо этого вы, вероятно, захотите использовать более безопасный snprintf. Один неэффективный, но безопасный способ сделать это:

int bufsize = snprintf(NULL, 0, formatstring, ...);
char *buffer = malloc(bufsize+1); # count doesn't include trailing nul
if (buffer == NULL) out_of_memory_error();
snprintf(buffer, bufsize+1, formatstring, ...);
person ysth    schedule 07.12.2008

Большое спасибо! Поскольку мне нужен был char*, я переписал код так:

for(i = 0;(i - 1)< n;i++)
{
char* b;
char a[100];
b = a;
sprintf(b, "%d", i);
}

и это работает как шарм. Наконец-то я могу жить дальше! Еще раз большое спасибо!

person user37875    schedule 07.12.2008
comment
Вы могли бы просто использовать a вместо b там. Что вы делаете с ним потом? Если ваш char* указывает на такой автоматический массив, он не будет надежным после блока, в котором объявлен массив. - person ysth; 07.12.2008