由于未使用int而导致分段错误



我不明白为什么我对int y的声明会阻止我的程序出现分段错误。该程序对那里的声明做了预期的处理,但如果我注释掉或删除它,就会给我一个分段错误:

uint8_t chunk[CHUNKS];
int x = 0; int y;
char filename[6];
FILE *card = fopen(argv[1], "r");
FILE *img = fopen(filename, "w");
//reads 512 byte chunks
while (fread(chunk, sizeof(uint8_t), CHUNKS, card) >= CHUNKS)
{
//checks first 4 bytes for jpeg signature
if (chunk[0] == 0xff && chunk[1] == 0xd8 && chunk[2] == 0xff && (chunk[3] & 0xf0) == 0xe0)
{
//if second or more jpeg, close old file first
if (x > 0)
{
fclose(img);
sprintf(filename, "%03i.jpg", x);
x++;
img = fopen(filename, "w");
//WCHUNKS += 512;
fwrite(chunk, sizeof(uint8_t)*CHUNKS, 1, img);
}


//if first jpeg
else
{
x++;
fclose(img);
//printf("I found %i Jpegsn", x);
sprintf(filename, "%03i.jpg", 0);
img = fopen(filename, "w");
fwrite (chunk, sizeof(uint8_t)*CHUNKS, 1, img);
//WCHUNKS += 512;
}
}

//if not a new jpeg, continue writing to current file
else
{
//WCHUNKS += 512;
fwrite (chunk, sizeof(uint8_t)*CHUNKS, 1, img);

}
}
fclose(img);
fclose(card);
}

如注释中所述,行:

sprintf(filename, "%03i.jpg", x);

将8个字节写入一个包含6个字符的数组,从而写入超过数组末尾。

但是,为什么声明一个额外的变量会有帮助呢?

从技术上讲,在C中写过数组的末尾是未定义的行为,但在实践中,额外的内存中总是有一些东西,局部变量通常在堆栈上连续排列。

通过在filename数组之前声明一个额外的未使用的int,编译器排列这些变量的方式,实际上向数组中添加了4个(可能是8个(字节。

如果没有它们,你会阻塞x,导致它有一个巨大的数字,这将迫使sprintf在数组末尾写入更多的字节,这将阻塞一些没有分配给变量的内存,这就是你出现分段错误的原因。

您通常可以查看程序集,或者使用调试器来了解变量在内存中的排列方式,从而了解当您写入其中一个变量时会发生什么。

最新更新