c语言 - 尝试读取每字节的图像字节时出现分段错误 11



我试图编写一个简单的C代码来计算一个字节在文件中重复的次数。我们尝试了带有.txt文件的代码,并创造了奇迹(测试的最大大小:137MB)。但是当我们尝试使用图像(即使是小图像,2KB)时,它返回了分段错误 11

我已经做了一些研究,并找到了一些特定的图像库,但我不想求助于它们,因为它的代码不仅适用于图像,而且几乎适用于任何类型的文件。有没有办法简单地读取每个字节的文件字节,而不考虑其他任何事情(扩展名、元等)。

这是代码:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
FILE *f;
char *file;
long numTotalBytes = 0;
int bytesCount[256] = {0}; 
f = fopen ( argv[1], "rb");
fseek(f, 0L, SEEK_END);
numTotalBytes = ftell(f);
rewind(f);
file = calloc(1, numTotalBytes);    
fread(file, numTotalBytes, 1, f);
fclose(f);
printf("numTotalBytes: %ld", numTotalBytes); //<- this gives the right output even for images
unsigned int i;
for (i=0; i<numTotalBytes; ++i) {
unsigned char pointer = file[i]; //<- This access fails at file[1099]
int pointer_int = (int)pointer;
printf("iteration %i with pointer at %in", i, pointer_int); //<- pointer_int is never below 0 or above 255
//++bytesCount[(int)file[i]];
++bytesCount[pointer_int];
}
free(file);
}

一些额外的信息:
- 将 img 的扩展名更改为 .txt 不起作用。 - 代码在迭代 1099 时完全返回分段错误(我使用的文件是 aprox 163KB,所以文件 [i] 应该接受最多 aprox 文件[163000]的访问)。
- 对于txt文件工作完美。
逐个读取字节并按预期对其进行计数,而不考虑文件大小。
- 我在Mac上(你永远不知道...

编辑:我已经编辑了代码,使其更具解释性和解释性,因为你们中的一些人告诉我我已经尝试过的事情。

EDIT_2:好的,伙计们,没关系。这个版本应该可以在任何其他不是我的计算机上工作。我认为问题出在传递参数时我的终端,但我刚刚切换了操作系统并且它可以工作。

  • 请检查fopen()calloc()是否成功。
  • 打印long的格式说明符是%ld,而不是%lu
  • (int)file[i]对数组索引不利,因为如果所有可以表示为char的值都可以在int中表示,则char转换为int将保留其值,并且因为如果char在您的环境(和设置)中签名,它可能会访问负索引,导致超出范围的访问并调用未定义的行为

应将++bytesCount[(int)file[i]];更改为++bytesCount[(unsigned char)file[i]];以防止使用负索引。

另请注意,二进制流(N1570 7.21.9.2 fseek 函数)可能支持带SEEK_ENDftell(),因此最好使用fgetc()逐个读取,以避免未定义的行为并使用更少的内存。

MikeCAT 只是打败了我。 接下来还有更多的解释,以防有帮助。

解决方法:将file更改为unsigned char *file,并将增量更改为++bytesCount[file[i]];

解释:根据这个答案,一个普通的char可能是signedunsigned。 在这种情况下,我猜它默认为signed. 这意味着任何值>=0x80都将成为负数。 这些值不太可能出现在您的英语文本文件中,但很可能在图像中! 要(int)的类型转换将保持负数为负数。 因此,代码将使用负数索引byteCounts,从而导致分段错误。

可能是由此行引起的

++bytesCount[(int)file[i]];

bytesCount是 256 个整数的数组。如果file[i]大于 256,则您正在访问无效内存,这可能会导致分段错误。

相关内容

  • 没有找到相关文章

最新更新