我在一个函数中使用 malloc 时遇到了困难,在该函数中我读取了一个带有 4 字节无符号整数的二进制文件,释放了传递的数组引用,将其重新分配到新的大小,然后尝试访问数组的成员。我认为问题出在 uint32_t 类型,因为该数组似乎被视为 8 字节整数数组,而不是 4 字节整数数组。不完全确定我哪里出错了,可能是使用 malloc,IE 也许我需要指示它以与我正在做的不同的方式创建 uint32_t 类型,或者可能是其他的东西。代码:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <malloc.h>
int filecheck (uint32_t **sched, int * count) {
int v, size = 0;
FILE *f = fopen("/home/pi/schedule/default", "rb");
if (f == NULL) {
return 0;
}
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
int schedsize = sizeof(uint32_t);
int elementcount = size / schedsize;
free(*sched);
*sched = malloc(size);
if (elementcount != fread(sched, schedsize, elementcount, f)) {
free(*sched);
return 0;
}
fclose(f);
// This works correctly and prints data as expected
for (v=0;v<elementcount;v++) {
printf("Method 1 %02d %u \n", v, ((uint32_t*)sched)[v]);
}
// This skips every other byte byt does not print any numbers > 32 bit unsigned
for (v=0;v<elementcount;v++) {
printf("Method 2 %02d %u \n", v, sched[v]);
}
// This treats the binary file as if it was 64 bit uints, printing 64 bit numbers
for (v=0;v<elementcount;v++) {
printf("Method 3 %02d %lu \n", v, sched[v]);
}
*count = elementcount;
return 1;
}
int main (){
uint32_t *sched = NULL;
int i, count = 0;
if (filecheck(&sched, &count)) {
for (i=0;i<count;i++) { // At the next line I get a segmentation fault
printf("Method 4 %02d %u\n", i, sched[i]);
}
} else {
printf("Error\n");
}
return 0;
}
我按要求添加了文件读取代码。尝试以我正在做的方式访问 main() 中的数组 sched 将打印我正在读取的数据,就好像它是 8 字节整数一样。所以我猜 sched 被视为一个 64 位整数数组,而不是我定义的 32 位数组。我想这是因为我释放了它并再次在它上面使用了 malloc。但我相信我指示 malloc 它应该创建的类型是 uint32_t 所以我很困惑为什么数据没有被这样对待。
编辑:找到了一种让它工作的方法,但不确定它是否正确(方法1)。这是将此数组视为 uint32_t 类型的唯一且最干净的方法吗?当然,编译器应该知道我正在处理的类型,而无需我每次使用它时都必须转换它。
编辑:实际上,当我尝试在 main 中访问它时,我遇到了段错误。我在代码中添加了一条注释来反映这一点。我之前没有注意到这一点,因为我在几个地方使用了 for print 循环来跟踪编译器如何查看数据。
编辑:不确定是否有办法添加二进制数据文件。我是在十六进制编辑器中手工制作的,它的确切内容并不那么重要。在 bin 文件中,FF FF FF FF FF FF FF FF 应该被读取为 2 个 uint32_t 类型,而不是 1 个 64 位整数。Fread AFAIK 不关心这一点,它只是填充缓冲区,但如果那是错误的,则需要更正。
TIA,皮特