【问题标题】:Segmentation fault without defining an unused array未定义未使用数组的分段错误
【发布时间】:2015-03-02 22:38:30
【问题描述】:

我正在尝试编写一个简单的程序,以十六进制输出 16 位块中二进制文件 (Game Boy ROM) 的前 16 KB。然而,在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]; 

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

【问题讨论】:

    标签: c arrays linux segmentation-fault


    【解决方案1】:

    在这一行:

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

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

    i &lt; (sizeof(buffer) / sizeof(buffer[0]))

    【讨论】:

    • 非常感谢,这解决了问题,我在循环期间不再遇到段错误。
    【解决方案2】:

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

    您可能希望交换第二个和第三个参数,有关用法示例,请参阅 here

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

    【讨论】:

    • 这也很有帮助,谢谢。我将该行更改为fread(buffer, 2, (sizeof(buffer) / sizeof(buffer[0])), ROM);,它给出了相同的输出,但应该更正确。考虑到我滥用该功能的严重程度,我很惊讶它甚至可以正常工作。
    猜你喜欢
    • 2012-05-25
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 2017-01-16
    相关资源
    最近更新 更多