将float指针设置为从头文件中读取的字符数组

时间:2017-06-09 16:15:35

标签: c arrays image pointers header

首先,抱歉这个问题很长,但应该很容易理解。假设我使用的结构图像包含通道,高度,宽度编号以及指向c*h*w个浮点值的实际图像数据的指针。我使用fwrite将图像结构数组和图像数据数组(每个图像的数据连接)写入单独的文件中,以便稍后将它们加载到另一个系统中。加载系统没有文件系统,所以我想将文件作为头文件传递,我使用xxd -i bin_file将存储的二进制文件数据转换为头文件中的字符数组(如下所示)。在加载程序中,图像数组和数据数组(图像的连接)只是#include头文件中声明的静态字符数组。我复制图像结构并覆盖数据指针以指向与每个图像的数据起始位置对应的数据元素。但是当我打印加载的数据时,只有第一个图像的一些起始数据是正确的,所有后续数据都是零。我无法弄清楚出了什么问题。有人能告诉我什么是错的吗? 下面显示了我制作的测试代码。 (对于channel = 2,height = 3,width = 4)。

=== image.h ===

typedef struct {
    int c;
    int h;
    int w;
    float *data;
} image;

=== store.c ===

#include <stdio.h>
#include "image.h"

float data1_0[24] = \
{0.840188,0.394383,0.783099,0.798440,0.911647,0.197551,0.335223,0.768230,0.277775,0.553970,0.477397,0.628871,0.364784,0.513401,0.952230,0.916195,0.635712,0.717297,0.141603,0.606969,0.016301,0.242887,0.137232,0.804177};

float data1_1[24] = \
{0.156679,0.400944,0.129790,0.108809,0.998925,0.218257,0.512932,0.839112,0.612640,0.296032,0.637552,0.524287,0.493583,0.972775,0.292517,0.771358,0.526745,0.769914,0.400229,0.891529,0.283315,0.352458,0.807725,0.919026};

image alpha_images[2];

main()
{

int i;
image ab;

alpha_images[0].c = 2;
alpha_images[0].h = 3;
alpha_images[0].w = 4;
alpha_images[0].data = data1_0;

alpha_images[1].c = 2;
alpha_images[1].h = 3;
alpha_images[1].w = 4;
alpha_images[1].data = data1_1;

FILE *fpi = fopen("alpha_image.bin","wb");
FILE *fpd = fopen("alpha_data.bin","wb");

for(i=0;i<2;i++){
    ab = alpha_images[i];
    if (fwrite(&ab, sizeof(image), 1, fpi) != 1) printf ("error! 1234 \n");
    if (fwrite(ab.data, ab.h*ab.w*ab.c, 1, fpd) != 1) printf ("error! 5678 \n");
}

printf("size of image = %d\n", sizeof(image));
}

xxd -i alpha_image.bin以十六进制显示下面显示的alpha_image_bin.h。

=== alpha_image_bin.h ===

unsigned char alpha_image_bin[] = {
  0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x80, 0x0b, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00
};
unsigned int alpha_image_bin_len = 48;

。 和xxd -i alpha_data.bin使alpha_data_bin.h以十六进制显示如下。

=== alpha_data_bin.h ===

nsigned char alpha_data_bin[] = {
  0x90, 0x16, 0x57, 0x3f, 0x92, 0xec, 0xc9, 0x3e, 0x2d, 0x79, 0x48, 0x3f,
  0x90, 0x66, 0x4c, 0x3f, 0xb3, 0x61, 0x69, 0x3f, 0xcf, 0x4a, 0x4a, 0x3e,
  0x76, 0x70, 0x20, 0x3e, 0x88, 0x48, 0xcd, 0x3e, 0xab, 0xe7, 0x04, 0x3e,
  0x41, 0xd7, 0xde, 0x3d, 0x8c, 0xb9, 0x7f, 0x3f, 0xc3, 0x7e, 0x5f, 0x3e
};
unsigned int alpha_data_bin_len = 48;

我在ieee754单精度浮点数(小端)表示时检查生成的值是否正确 转换后的头文件如下 === alpha_image_bin.h ===

unsigned char alpha_image_bin[] = {
  0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00
};

unsigned int alpha_image_bin_len = 48;

=== alpha_data_bin.h ===

unsigned char alpha_data_bin[] = {
  0x90, 0x16, 0x57, 0x3f, 0x92, 0xec, 0xc9, 0x3e, 0x2d, 0x79, 0x48, 0x3f,
  0x90, 0x66, 0x4c, 0x3f, 0xb3, 0x61, 0x69, 0x3f, 0xcf, 0x4a, 0x4a, 0x3e,
  0x76, 0x70, 0x20, 0x3e, 0x88, 0x48, 0xcd, 0x3e, 0xab, 0xe7, 0x04, 0x3e,
  0x41, 0xd7, 0xde, 0x3d, 0x8c, 0xb9, 0x7f, 0x3f, 0xc3, 0x7e, 0x5f, 0x3e
};
unsigned int alpha_data_bin_len = 48;

以下是加载程序。

=== load.c ===

#include <stdio.h>
#include <string.h>
#include "image.h"

#include "alpha_image_bin.h"
#include "alpha_data_bin.h"

image alpha_image[2];

main()
{

int i, j;

image *iptr = (image *)&alpha_image_bin[0];
int dptr = 0;
for(i = 0; i < 2; i++){
    alpha_image[i] = *iptr; // copy c,h,w
    alpha_image[i].data = (float *)&alpha_data_bin[dptr]; // overwrite data pointer
    iptr++; dptr+= 2*3*4*sizeof(float);
}

// check loading
for(i = 0; i < 2; i++){
    printf("c = %d, h = %d, w = %d\n", alpha_image[i].c, alpha_image[i].h, alpha_image[i].w);
    for(j=0; j<2*3*4; j++) {
        printf("%f ", alpha_image[i].data[j]);
    }
    printf("\n");
}
}

当我运行加载时,它会给我这个结果

===加载结果===

c = 2, h = 3, w = 4
0.840188 0.394383 0.783099 0.798440 0.911647 0.197551 0.156679 0.400944 0.129790 0.108809 0.998925 0.218257 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 
c = 2, h = 3, w = 4
0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 

正确的数据应如store.c所示。

===预期的正确结果===

float data1_0[24] = \
{0.840188,0.394383,0.783099,0.798440,0.911647,0.197551,0.335223,0.768230,0.277775,0.553970,0.477397,0.628871,0.364784,0.513401,0.952230,0.916195,0.635712,0.717297,0.141603,0.606969,0.016301,0.242887,0.137232,0.804177};

float data1_1[24] = \
{0.156679,0.400944,0.129790,0.108809,0.998925,0.218257,0.512932,0.839112,0.612640,0.296032,0.637552,0.524287,0.493583,0.972775,0.292517,0.771358,0.526745,0.769914,0.400229,0.891529,0.283315,0.352458,0.807725,0.919026};

load.c代码有什么问题? (注意sizeof(image)是24,因为在数据指针之前有4个字节的填充。)

2 个答案:

答案 0 :(得分:2)

float data1_0[24] = \中,您可以删除反斜杠。我不知道它是否会受伤,但它肯定没有必要,因为C编译器是行独立的(它只是继续在下一行解析)。

fwrite(&ab, sizeof(image), 1, fpi)中,您还在编写指向数据的指针。这是没用的,因为你无法用意义回读它。你可以读回来,但你必须忽略指针的任何值,并用指向实际数据的指针替换它。

最后,您忘记关闭文件,因此请向fclose()添加两次调用。

<小时/> 在load.c中我没有看到你打开任何文件,所以你怎么期望加载任何东西?啊......你把它保存为.bin,然后把它包含在.h中。听起来有点愚蠢:每次改变你都要重新编译它。如果我是老师,你就会因为这个设置而失败。只需使用malloc分配内存,然后将二进制数据读入其中。

答案 1 :(得分:0)

您描述的错误不在load.c中。它位于store.c

    if (fwrite(ab.data, ab.h*ab.w*ab.c, 1, fpd) != 1) printf ("error! 5678 \n");

这只写24ab.data个字节,而不是写所有24 * sizeof (float)个字节(假设float是4个字节,你只写了每个的前6个浮点数图像)。

通过更改为:

来修复它
    if (fwrite(ab.data, sizeof(float)*ab.h*ab.w*ab.c, 1, fpd) != 1) printf ("error! 5678 \n");

由于该错误,您在文件中创建的alpha_data_bin.h中的char数组太短。