【问题标题】:printf access violation in subfunction - Ansi C90子函数中的 printf 访问冲突 - Ansi C90
【发布时间】:2012-11-16 14:30:02
【问题描述】:

在子函数中调用 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
}

来自我的 stachtrace:

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 像那样崩溃?

【问题讨论】:

  • 您可能在其他地方有堆栈损坏。这段代码对我来说似乎没问题。尝试使用一些动态代码分析工具来跟踪访问违规。也尝试使用 VS 中的“调试”运行代码

标签: printf access-violation ansi c89


【解决方案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 是一个字符串。实际上 str 不是字符串而是结构。此错误可能出现在任何地方,尤其是在结构的内容被其他信息扩展时(例如size_t size)。

我应该写:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多