子函数中的 printf 访问冲突 - Ansi C90

问题描述 投票:0回答:1

在子函数内调用 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 像那样崩溃?

printf access-violation c89 ansi-c
1个回答
0
投票

错误是我期望 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);
}
© www.soinside.com 2019 - 2024. All rights reserved.