分段错误,无需定义未使用的阵列

时间:2015-01-05 11:36:29

标签: c arrays linux segmentation-fault

我正在尝试编写一个简单的程序,以十六进制的形式输出16位块中的前16千字节二进制文件(Game Boy ROM)。但是在for循环期间,我的程序总是会出现段错误,但它总是会在数组中的不同点发生段错误。这是代码:

#include <stdio.h>
#include <stdint.h>

int main ()
{
    uint16_t buffer[8000];
    FILE* ROM = fopen("rom.gb", "rb");
    if (ROM == NULL)
    {
        printf("Error");
        fclose(ROM);
        return 1;
    }
    fread(buffer, sizeof(buffer), 1, ROM);
    int i;
    for(i = 0; i < sizeof(buffer); ++i)
    {
        if (buffer[i] < 16)
        {
            printf("000%x ", buffer[i]);
        }
        else if (buffer[i] < 256)
        {
            printf("00%x ", buffer[i]);
        }
        else if (buffer[i] < 4096)
        {
            printf("0%x ", buffer[i]);
        }
        else
        {
            printf("%x ", buffer[i]);
        }
    }
    fclose(ROM);
    return 0; 
}

在我改为使用uint16_t而不是char之前(因为Game Boy有一个16位的地址空间),这没有发生,事实上如果我包含声明

unsigned char buffer2[16000]; 

在第一个缓冲区的声明旁边,我得到了预期的输出。所以我的问题是,为什么添加一个未使用的变量会阻止程序进行segfaulting?我怎样才能避免必须这样做并声明一个在程序中完全未使用的巨大数组呢?

2 个答案:

答案 0 :(得分:10)

在这一行:

for(i = 0; i < sizeof(buffer); ++i)

sizeof(buffer)是数组的大小(以字节为单位),如果您想要使用

的元素数

i < (sizeof(buffer) / sizeof(buffer[0]))

答案 1 :(得分:1)

我不确定您是否正确使用fread,如果您查看documentation,则第二个参数是每个元素的大小,而您是&#39}传递整个缓冲区的大小。

您可能想要交换第二个和第三个参数,请参阅here了解用法示例。

另外请注意Alter Mann指出,你需要将缓冲区的大小除以其类型的大小。