为什么遍历十六进制数组会提前停止?
Why does iterating over a hex array stop early?
问题和代码
我正在使用代码在 Raspberry Pi 上截取屏幕截图。使用 VC 处理程序的一些魔法,我可以截取屏幕截图并使用 calloc
将其存储在内存中。我可以使用它来将数据作为 ppm
图像存储在文件中,其中包含必要的 header 使用:
void * image;
image = calloc(1, width * 3 * height);
// code to store data into *image
FILE *fp = fopen("myfile.ppm", "wb");
fprintf(fp, "P6\n%d %d\n255\n", width, height);
fwrite(image, width*3*height, 1, fp);
fclose(fp);
这样就成功存储了数据。我可以正常访问和查看。
但是,如果我改为尝试通过打印来检查为了调试目的而放入文件中的数据:
int cnt = 0;
std::string imstr = (char *)image;
for (int i=0; i<(width*3*height); i++) {
std::cout << (int)imstr[i] << " " << cnt << std::endl;
cnt += 1;
}
我segfault
早。打印中返回的数字对上下文有意义(例如颜色值 <255)
示例编号
在 1280 x 768 x 3 图像的情况下,我的 cnt
停止在 64231。它停止的值似乎与 sizeof
[=17] 没有任何关系=] 或 int
.
我想我在这里遗漏了一些明显的东西,但我看不到。有什么建议吗?
很可能你在 (char *)image
中至少有一个空字符,所以 std::string
长度比 width*3*height
短,因为它的初始化是因为只有第一个空字符之前的字符使用字符
使用 std::array
而不是像那样初始化的 std::string
您将 image
数据转换为 std::string
的方式是错误的。如果 image
的原始数据包含任何 0x00
字节,那么 std::string
将被截断,导致您的循环访问超出 std::string
的范围。如果 image
的原始数据不包含任何 0x00
字节,那么 std::string
构造函数将尝试读取超出 image
分配内存的边界。
构造std::string
时需要考虑image
的大小,例如:
size_t cnt = 0;
std::string imstr(static_cast<char*>(image), width*3*height);
for (size_t i = 0; i < imstr.size(); ++i) {
std::cout << static_cast<int>(imstr[i]) << " " << cnt << std::endl;
++cnt;
}
否则,根本不要将 image
转换为 std::string
。您可以直接迭代 image
的原始数据,例如:
size_t cnt = 0, imsize = width*3*height;
char *imdata = static_cast<char*>(image);
for (size_t i = 0; i < imsize; ++i) {
std::cout << static_cast<int>(imdata[i]) << " " << cnt << std::endl;
++cnt;
}
问题和代码
我正在使用代码在 Raspberry Pi 上截取屏幕截图。使用 VC 处理程序的一些魔法,我可以截取屏幕截图并使用 calloc
将其存储在内存中。我可以使用它来将数据作为 ppm
图像存储在文件中,其中包含必要的 header 使用:
void * image;
image = calloc(1, width * 3 * height);
// code to store data into *image
FILE *fp = fopen("myfile.ppm", "wb");
fprintf(fp, "P6\n%d %d\n255\n", width, height);
fwrite(image, width*3*height, 1, fp);
fclose(fp);
这样就成功存储了数据。我可以正常访问和查看。
但是,如果我改为尝试通过打印来检查为了调试目的而放入文件中的数据:
int cnt = 0;
std::string imstr = (char *)image;
for (int i=0; i<(width*3*height); i++) {
std::cout << (int)imstr[i] << " " << cnt << std::endl;
cnt += 1;
}
我segfault
早。打印中返回的数字对上下文有意义(例如颜色值 <255)
示例编号
在 1280 x 768 x 3 图像的情况下,我的 cnt
停止在 64231。它停止的值似乎与 sizeof
[=17] 没有任何关系=] 或 int
.
我想我在这里遗漏了一些明显的东西,但我看不到。有什么建议吗?
很可能你在 (char *)image
中至少有一个空字符,所以 std::string
长度比 width*3*height
短,因为它的初始化是因为只有第一个空字符之前的字符使用字符
使用 std::array
而不是像那样初始化的 std::string
您将 image
数据转换为 std::string
的方式是错误的。如果 image
的原始数据包含任何 0x00
字节,那么 std::string
将被截断,导致您的循环访问超出 std::string
的范围。如果 image
的原始数据不包含任何 0x00
字节,那么 std::string
构造函数将尝试读取超出 image
分配内存的边界。
构造std::string
时需要考虑image
的大小,例如:
size_t cnt = 0;
std::string imstr(static_cast<char*>(image), width*3*height);
for (size_t i = 0; i < imstr.size(); ++i) {
std::cout << static_cast<int>(imstr[i]) << " " << cnt << std::endl;
++cnt;
}
否则,根本不要将 image
转换为 std::string
。您可以直接迭代 image
的原始数据,例如:
size_t cnt = 0, imsize = width*3*height;
char *imdata = static_cast<char*>(image);
for (size_t i = 0; i < imsize; ++i) {
std::cout << static_cast<int>(imdata[i]) << " " << cnt << std::endl;
++cnt;
}