在对C中的二进制文件进行fread时检测到堆栈崩溃

在对C中的二进制文件进行fread时检测到堆栈崩溃,c,image,binary,fread,stack-smash,C,Image,Binary,Fread,Stack Smash,在底部更新==== 所以不久前我做了以下函数,我成功地用它从转换成.bin文件的图像(w x h维)中获取灰度值。它只给出一个包含所有像素值的数组。 但是,它不是像这样的函数,而是立即放入main()中 我决定扩展代码,因此我将其重写为上一个函数,并将其放在单独的函数文件中,还制作了一个头文件。函数的额外文件和头文件100%工作,所以这不是问题所在。现在,这段代码不再工作了,我得到了一个堆栈崩溃错误。在此函数之后调用的一些变量也跳到了另一个值,因此我认为问题出在缓冲区上(我不知道缓冲区的正确大小

在底部更新====

所以不久前我做了以下函数,我成功地用它从转换成.bin文件的图像(w x h维)中获取灰度值。它只给出一个包含所有像素值的数组。 但是,它不是像这样的函数,而是立即放入main()中

我决定扩展代码,因此我将其重写为上一个函数,并将其放在单独的函数文件中,还制作了一个头文件。函数的额外文件和头文件100%工作,所以这不是问题所在。现在,这段代码不再工作了,我得到了一个堆栈崩溃错误。在此函数之后调用的一些变量也跳到了另一个值,因此我认为问题出在缓冲区上(我不知道缓冲区的正确大小,但它起作用了…)。经过一些实验和测试,我提出了以下功能。我用名为image2的字符数组替换了缓冲区,以便简单地尝试和测试它:

void decodeBIN(const char* filename, short image[], int w, int h){
    int i = 0, res;
    char image2[];
    FILE *ptr;

    ptr = fopen(filename, "rb"); //"MySnap_20180327-2239-010.bin"
    if (!ptr){
        printf("\nUnable to open file!\n"); // error
    }

    res = fread(image2,1,w*h,ptr) // need to read w*h pixels

    while (i < w*h){ // DEBUG
        printf("%i ", (int)image2[i]); // DEBUG
        i++;
    }
    printf("\nRead %u bytes\n", res); // DEBUG
    fclose(ptr);
    printf("Binary image read (npixels: %i).\n", i); // DEBUG
}
但是分段错误和跳跃变量仍然存在,因此这里是对我所做工作的更高层监督:

char filenamePathed["[path of file]/file.bin"];
short img1[npixels]; // npixels = w*h
printf("i_file: %i\n", i_file); // correct value
decodeBIN(filenamePathed, img_curr, w, h); // decode bin
printf("i_file: %i\n", i_file); // value jumped
while (i < npixels){
    img1[i] = (short)img_curr[i];
    i++;
}
charfilenamepathed[“[path of file]/file.bin]”;
短img1[n像素];//n像素=w*h
printf(“i_文件:%i\n”,i_文件);//正确值
decodeBIN(文件名路径,img_curr,w,h);//解码箱
printf(“i_文件:%i\n”,i_文件);//价值跃升
而(i

也许知道我正在对多个文件(时间序列)迭代执行此操作是件好事?我还需要它以(短)格式结束(或整数,但最终需要内存效率高,像素的范围为0-255,因此int有点丰富)。

第二个函数的问题是,在数组
image2
中写入时,没有为其保留空间。声明
charimage2[]
仅表示存在一个数组,并且可以在var
image2
中找到该数组的地址,但没有与之关联的空格,因此出现了问题

可以通过多种方式将空间与此数组关联

在堆中使用永久存储

image2=malloc(x*y);//但不要忘记在函数结束时释放(图像2)

在堆栈中使用临时存储(离开函数时会自动释放空间)

image2=alloca(x*y);//略快于malloc,无需释放()图像

但最好是使用参数化大小的数组(从C99开始)。您的数组应声明为

char-image2[w*h];//将使用w和h的值定义数组大小

如果您不想在函数中打印图像值,还想做其他事情,那么您应该将图像存储在永久内存中,并有一个知道程序中数组地址的方法。这可能是您想要的,也是您在参数列表中有
short image[]
的原因

解决方案只是简单地使用
image
而不是
fread()
中的
image2

但是,
image
的声明应该是一致的,而image应该是
char
而不是
short
的数组


还要注意声明。在第一个函数中,图像是一个
无符号字符数组
,在第二个函数中是一个
字符数组
。虽然存储大小相同,
fread()
将存储相同的值,但它们并不相等。如果在算术上下文中使用,
image[i]
将得到不同的解释,结果也可能不同。一般来说,图像是无符号的,显然,问题在于图像的分配,尽管我不知道为什么它是错误的。 我过去常常给它分配
无符号字符图像[npixels]
错误的解决方案似乎是
无符号字符图像[npixels*7]

不知怎么回事,但如果有人有解释,请这样做:)

您将
fread()
放入一个不存在的缓冲区(
image2[]
指向任何地方),谢谢您的快速评论!这实际上是一个诚实的错误,但这并没有最终解决它。谢谢你的详细解释,我非常喜欢。我应用了您的解决方案,并以以下内容结束:
void decodeBIN(const char*filename,unsigned char image[],int w,int h){int I=0,res;FILE*ptr;res=fread(image,sizeof(char),w*h,ptr)//需要读取w*h像素fclose(ptr);}
即使这确实给出了正确的输出,我仍然得到分割错误(核心转储)和之后的跳跃变量。这是否表明它在后面的代码中?很难说。如果分配了
图像
,则此功能应该是正确的。问题应该在代码的其余部分。好的,谢谢!你能帮我看一下更新吗?也许那里有些有用的东西?
void decodeBIN(const char* filename, unsigned char image[], int w, int h){
    int i = 0, res;
    FILE *ptr;

    res = fread(image,sizeof(char),w*h,ptr) // need to read w*h pixels
    fclose(ptr);
}
char filenamePathed["[path of file]/file.bin"];
short img1[npixels]; // npixels = w*h
printf("i_file: %i\n", i_file); // correct value
decodeBIN(filenamePathed, img_curr, w, h); // decode bin
printf("i_file: %i\n", i_file); // value jumped
while (i < npixels){
    img1[i] = (short)img_curr[i];
    i++;
}