在子功能内调用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崩溃?
答案 0 :(得分: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);
}