【问题标题】:Reallocating Structure? Copy paste structure重新分配结构?复制粘贴结构
【发布时间】:2020-04-23 22:23:20
【问题描述】:

您好,我的任务是将完整结构复制到一个新结构中,并分配结构内存。 我想将一个结构复制到另一个结构中,并且我想复制它的内存。所以如果我“释放”第一个结构,那么我就会在内存中找到这些信息。

 struct bmp_image* flip_vertically(const struct bmp_image* image) {
    struct bmp_image* bmp = NULL;
    bmp = (struct bmp_image*)realloc(bmp, sizeof(struct bmp_image)); 
    memcpy(bmp, image, sizeof(struct bmp_image));

   return bmp;
}

可能是什么问题?

例如:

如果我知道

image->data[5].blue 是 255,我想复制它,但我还需要将该信息保存到内存中

主要任务是翻转bmp图片。一切对我来说都很完美,但是如果我将这个源代码用于测试,它会这样写:

Running suite(s): flip_horizontally()

stderr

double free or corruption (!prev)

这意味着测试在某个地方释放了旧结构,所以我在新结构中没有这些信息

struct bmp_header{
    uint16_t type;              // "BM" (0x42, 0x4D)
    uint32_t size;              // file size
    uint16_t reserved1;         // not used (0)
    uint16_t reserved2;         // not used (0)
    uint32_t offset;            // offset to image data (54B)
    uint32_t dib_size;          // DIB header size (40B)
    uint32_t width;             // width in pixels
    uint32_t height;            // height in pixels
    uint16_t planes;            // 1
    uint16_t bpp;               // bits per pixel (1/4/8/24)
    uint32_t compression;       // compression type (0/1/2) 0
    uint32_t image_size;        // size of picture in bytes, 0
    uint32_t x_ppm;             // X Pixels per meter (0)
    uint32_t y_ppm;             // X Pixels per meter (0)
    uint32_t num_colors;        // number of colors (0)
    uint32_t important_colors;  // important colors (0)
} __attribute__((__packed__));


/**
 * This structure describes a color consisting of relative intensities of
 * red, green, and blue.
 */
struct pixel {
    uint8_t blue;
    uint8_t green;
    uint8_t red;
    //uint8_t alpha;
} __attribute__((__packed__));


/**
 * Structure describes the BMP file format, which consists from two parts:
 * 1. the header (metadata)
 * 2. the data (pixels)
 */
struct bmp_image {
    struct bmp_header* header;
    struct pixel* data;         // nr. of pixels is `width` * `height`
};

Main.c

int main () {
struct bmp_image* image = NULL;
    FILE *stream = fopen("assets/saboteur.bmp", "r");
    image = read_bmp(stream);

    FILE *output_p1 = fopen("square2.bmp", "w");
    struct bmp_image* newimage1 = NULL;
    newimage1 = flip_vertically(image);
    free_bmp_image(image);
    write_bmp(output_p1, newimage1);

    free(newimage1);     
    fclose(output_p1);
    fclose(stream);
    return 0;
}

如果我释放图像(旧结构),它会向我显示很多错误,我无法将其写入文件。这对我来说意味着它想从旧结构中读取。

【问题讨论】:

  • 看起来不错,但为什么在 malloc 可以使用时使用 realloc?你的问题是什么?如果bmp_image 包含指向数据的指针并且您也想复制它,则必须手动进行。分配一个新结构是不够的,因为你只是复制了指针
  • 您遇到了哪些具体问题?是什么让您怀疑该代码存在问题?如果您需要进一步的帮助,请提供minimal verifiable example 以及您可能遇到的错误。包括输入、预期结果和实际结果。
  • 如前所述 - 您需要提供一个最小的可验证示例。例如,我们不知道struct bmp_image 是如何定义的,这在这里可能很关键。 “我想复制它,但我还需要将该信息保存到内存中”——这就是你想要做的,但你还没有告诉我们你有什么问题。你撞车了吗?你在某处得到不正确的结果吗?等等
  • 如果struct bmp_image 的定义如您的other question 中所示,那么问题就像我们中的一些人所猜测的那样。 mempcy 进行“浅层”复制。它复制结构中的指针值,而不是它们指向的内容。您需要为每个结构成员分配内存并为每个成员执行memcpy

标签: c pointers structure


【解决方案1】:

memcpy 进行“浅”复制而不是“深”复制。浅拷贝将只复制struct bmp_image 中的指针值,而不是它指向的内存。要进行深度复制,需要分配和复制各个字段。这是一些说明性代码。为简洁起见省略了错误检查,但对于最终代码,应检查所有分配结果。

struct bmp_image* flip_vertically(const struct bmp_image* image) {
    bmp = malloc(sizeof(*bmp)); 

    bmp->header = malloc(sizeof(*(bmp->header)));
    *bmp->header = *(image->header);

    size_t pixel_data_size =
        sizeof(*(bmp->data)) * bmp->header->width * bmp->header->height;
    bmp->data = malloc(pixel_data_size);
    memcpy(bmp->data, image->data, pixel_data_size);

   return bmp;
}

【讨论】:

  • 哦,我才注意到原来的函数名是flip_vertically。显然显示的代码只是复制而不是翻转。
  • IIRC, sizeof(*(bmp->data)) * bmp->header->width 可能需要填充到 2 或 4 的倍数。嗯。
  • 请问,flip_horizo​​ntally 有什么不同吗?
  • @Tchiggy 它只在内存中分配结构,翻转的主要功能不在此处,但在水平翻转中分配与此处相同
猜你喜欢
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 2021-07-17
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2011-10-28
  • 2018-06-08
相关资源
最近更新 更多