我正在使用从单个文件读取并使用 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
条件,什么都不做,然后返回错误。
最佳答案
除了 char * filename;
的问题,它应该是一个数组,例如char filename[64];
,这里有问题:
(array[3] & 0xf0==0)
如何评估?
是 ((array[3] & 0xf0)==0)
还是 (array[3] & (0xf0==0))
?
结帐 https://en.cppreference.com/w/c/language/operator_precedence并且您会看到 ==
的优先级高于 &
。因此,您首先执行 0xf0 == 0
。那总是假的(又名零)所以你的表达总是假的。因此允许编译器(并且可能会)优化生成的代码,以便在运行时不评估表达式。相反,它总是直接转到 else if
部分。
换句话说 - 允许编译器将您的代码视为:
while(fread(array,sizeof(char *),512,source)==512)
{
if(active_read==1)
fwrite(array, sizeof(char *), 512, image);
^^^^^^^^^^^^^^
}
编辑:另请注意,这应该
是 sizeof(char)
或只是 1(因为 sizeof(char) 总是 1)
正如@Jabberwocky 在评论中指出的那样。
顺便说一句:小心 sprintf
,因为它可能会溢出目标缓冲区。考虑改用 snprintf
。
关于c - "*** stack smashing detected ***"带文件读写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63736352/