нарушение доступа к printf в подфункции - Ansi C90

Вызов printf внутри подфункции приводит к нарушению прав доступа.

Программа довольно большая по размеру. но я смог изолировать проблему до такой степени, что выполняется только вызов подфункции.

я могу вывести систему из строя, вызвав printf с такой буквальной константой: printf("test"). Некоторые другие люди также имели нарушения доступа, передавая странный объект в printf - здесь это не так.

Вот некоторый псевдокод:

subfunction()
{
    printf("all works great"); //Access Violation

    //some other calls here
}

void main()
{
    otherfunctions(); //
    printf("all works great");
    subfunction();        
    //some more calls here
}

Из моего стахтрейса:

msvcr100d.dll!_chkstk()
msvcr100d.dll!_write(int fh, const void * buf, unsigned int cnt)
msvcr100d.dll!_flush(_iobuf * str)
msvcr100d.dll!_ftbuf(int flag, _iobuf * str)
msvcr100d.dll!printf(const char * format, ...)

Код находится в коде C90 и компилируется с VS2010. Его следует рассматривать как C90. Это произошло после рефакторинга, когда все _(v)snprintf были заменены на их аналоги _(v)snprintf_s. Не уверен, что это повлияло.

Я думаю, что буфер очищается до того, как в него что-то записывается.

Как я могу исследовать это дальше? Какие системные настройки могут коснуться моего другого кода, чтобы вызвать такой сбой printf?


person Johannes    schedule 16.11.2012    source источник
comment
Вероятно, у вас есть повреждение стека где-то еще. Этот код кажется мне правильным. Попробуйте использовать какой-нибудь инструмент динамического анализа кода для отслеживания нарушений прав доступа. Также попробуйте запустить код с помощью Debug в VS.   -  person Ivaylo Strandjev    schedule 16.11.2012


Ответы (1)


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

Для Ansi-C я обычно пишу структуру для инкапсуляции строк.

typedef struct TString{
    char buffer[2000];
}TString;

Я склонен писать:

void mistake( void ){
    TString str;
    TStrnig_Construct(&str);
    prtinf( "%s", str );
    TString_Destuct(&str);
}

Мне это трудно заметить, так как это действительно похоже на строку. На самом деле str — это не строка, а структура. Эта ошибка может проявиться где угодно, особенно если содержимое структуры дополнено другой информацией (например, size_t size).

Я должен был написать:

void corrected( void ){
    TString str;
    TStrnig_Construct(&str);
    prtinf( "%s", str.buffer );
    TString_Destuct(&str);
}
person Johannes    schedule 13.05.2013