【发布时间】:2020-12-23 10:36:43
【问题描述】:
我正在使用一个从单个文件读取并使用sprintf 将该数据写入多个文件的 C 程序,我在某个地方出错了,但我真的不知道在哪里以及这会导致错误:
*** stack smashing detected ***
这里给出了可用于复制的代码:
FILE * source=fopen("card.raw","r");// defines source I will read from
char array[512];
int active_read=0;
char * filename;
sprintf(filename, "%03i.jpg",i);
FILE *image=fopen(filename, "a"); //my understanding of sprintf to create a file
while(fread(array,sizeof(char *),512,source)==512) // if 512 characters can be detected
{
if(array[0]==0xff && array[1]==0xd8 && array[2]==0xff && (array[3] & 0xf0==0))
{
if(active_read==1)
fclose(image);
active_read=1;
sprintf(filename, "%03i.jpg",i);
image=fopen(filename, "a");
fwrite(array, sizeof(char *),512, image);
i++;
}
else if(active_read==1)
fwrite(array, sizeof(char *), 512, image);
}
我用我的调试器(CS50 调试器)对代码进行了排序。而且我发现if 条件甚至从未被检查过。它从while 循环跳转到else if 条件,从不执行任何操作然后返回错误。
【问题讨论】:
-
1)
filename未初始化,因此第一个sprintf已经给出了 UB。 2)fread(array,sizeof(char *),512,source)为什么是sizeof(char *)?array是char[],所以应该是sizeof(char)或简单的1。 -
filename应该是一个数组,而不是一个指针。 -
char * filename;->char filename[64]; -
@Mr.JohnnyDoe 这只是为了说明原理,即选择一个足够高的数字,这样您就不会溢出缓冲区。在“真实”代码中,您应该使用
snprintf -
active_read有点奇怪。我们看不到它是如何初始化的,它只被赋值为 1。您需要发布定义和初始化它的代码