简体   繁体   English

将指针存储为二维数组的问题

[英]Trouble Storing a Pointer as a Two Dimensional Array

First off, this is a snippet of code from my larger project, so please excuse the lack of error checks and other minor details.首先,这是我较大项目中的一段代码,所以请原谅缺少错误检查和其他小细节。 I excluded these details for readability.为了便于阅读,我排除了这些细节。
This snippet is supposed to read a .raw file and store the data into a uint16_t * then convert it into a 2D array which needs to be written back as an identical file using fwrite() .此代码段应该读取.raw文件并将数据存储到uint16_t *然后将其转换为需要使用fwrite()作为相同文件写回的二维数组。
I know for a fact that the data being written into image_ptr is correct.我知道写入image_ptr的数据是正确的。 I believe my problem is occuring when I am attempting to save the variable image_ptr into the 2D array named image in the main function or it is occurring within the fwrite() statement in my save_image function.我相信我的问题是在我尝试将变量image_ptr保存到main函数中名为image的二维数组中时发生的,或者它发生在我的save_image函数的fwrite()语句中。

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#define MAX_ROW 2560
#define MAX_COL 2160

uint16_t image[MAX_ROW][MAX_COL];

uint16_t* get_image_data(uint32_t image_index)
{
    int result;
    char filename[32];
    sprintf(filename, "image%d.raw", image_index);
    
    FILE *image_raw = fopen(filename, "rb");
    fseek(image_raw, 0, SEEK_END);
    long filesize = ftell(image_raw);
    rewind(image_raw);
    long num_samples = filesize / sizeof(uint16_t);

    /*READ IMAGE DATA*/
    uint16_t *image_data_ptr = (uint16_t*) malloc(filesize);
    size_t num_read = fread(image_data_ptr, sizeof(uint16_t), num_samples, image_raw);
    fclose(image_raw);
    
    return image_data_ptr;
}

int save_image()
{
    int row, col, pixel_index = 0;
    int data_size = MAX_ROW * MAX_COL;
    uint16_t * image_data = malloc((sizeof *image_data)*data_size);
    image_data = image[0];
    FILE *ptr_image_file;
    ptr_image_file = fopen("image21.raw", "wb");
    
    for(col = 0; col < MAX_COL; col++) 
    {
        if(**(image + col) != 0)
        {
            if (fwrite(*(image + col), sizeof(uint16_t), MAX_ROW, ptr_image_file) != MAX_ROW) 
            {
                fprintf(stderr, "Can't write to output file\n");
                fclose(ptr_image_file);
                return -1;
            }
        }
    }
    
    fclose(ptr_image_file);
    return 0;
}

int main()
{
    uint16_t * image_ptr = malloc((sizeof *image_ptr)*MAX_ROW*MAX_COL);
    //Get Image Data
    image_ptr = get_image_data(1);
    
    int row, col, pixel_index = 0;
    for(col = 0; col < MAX_COL; col++) 
    {
        for(row = 0; row < MAX_ROW; row++) 
        {
            *(*(image + col) + row) = *(image_ptr + pixel_index);
            pixel_index++; 
        }
    }
    
    save_image();
    
    return 0;
}

Your code is trying to use a global image buffer and buffers from malloc in several places, causing memory leaks.您的代码试图在多个地方使用全局图像缓冲区和来自malloc缓冲区,从而导致内存泄漏。

Your transform using pixel_index is unclear as to intent.您使用pixel_index转换的意图不清楚。

You're using pointers to the wrong buffers in most cases, working on images that have no data.在大多数情况下,您正在使用指向错误缓冲区的指针,处理没有数据的图像。

Your pointer indexing is incorrect.您的指针索引不正确。

Here is a refactored version of the code.这是代码的重构版本。

I've used cpp conditionals to denote old vs. new code:我使用cpp条件来表示旧代码与新代码:

#if 0
// old code
#else
// new code
#endif

The code has annotations for the bugs.该代码具有错误的注释。 I've compiled it but not tested it:我已经编译它但没有测试它:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#define MAX_ROW 2560
#define MAX_COL 2160

#if 0
uint16_t image[MAX_ROW][MAX_COL];
#endif

uint16_t *
get_image_data(uint32_t image_index)
{
#if 0
    int result;
#endif
    char filename[32];

    sprintf(filename, "image%d.raw", image_index);

    FILE *image_raw = fopen(filename, "rb");

    fseek(image_raw, 0, SEEK_END);
    long filesize = ftell(image_raw);

    rewind(image_raw);

// NOTE/BUG: what if filesize is odd?
    long num_samples = filesize / sizeof(uint16_t);

    /* READ IMAGE DATA */
// NOTE/BUG: don't cast the return value of malloc
#if 0
    uint16_t *image_data_ptr = (uint16_t *) malloc(filesize);
#else
    uint16_t *image_data_ptr = malloc(filesize);
#endif
    size_t num_read = fread(image_data_ptr, sizeof(uint16_t), num_samples,
        image_raw);
    if (num_read != num_samples) {
        perror("fread");
        exit(1);
    }

    fclose(image_raw);

    return image_data_ptr;
}

int
save_image(uint16_t *image_ptr)
{
#if 0
    int row, col, pixel_index = 0;
    int data_size = MAX_ROW * MAX_COL;
#else
    int row;
#endif

// NOTE/BUG: this blows away the pointer you just got from malloc and created
// a memory leak
// NOTE/BUG: this allocated array has no valid data
#if 0
    uint16_t *image_data = malloc((sizeof *image_data) * data_size);
    image_data = image[0];
#endif
    FILE *ptr_image_file;

    ptr_image_file = fopen("image21.raw", "wb");

#if 0
    for (col = 0; col < MAX_COL; col++) {
// NOTE/BUG: should always write the data
        if (**(image + col) != 0) {
// NOTE/BUG: wrong way to index into image
            if (fwrite(*(image + col), sizeof(uint16_t), MAX_ROW, ptr_image_file) != MAX_ROW) {
                fprintf(stderr, "Can't write to output file\n");
                fclose(ptr_image_file);
                return -1;
            }
        }
    }
#else
    // output image row-by-row
    for (row = 0; row < MAX_ROW; row++) {
        // output single row
        if (fwrite(&image_ptr[row * MAX_COL], sizeof(uint16_t), MAX_COL,
            ptr_image_file) != MAX_COL) {
            fprintf(stderr, "Can't write to output file\n");
            fclose(ptr_image_file);
            return -1;
        }
    }
#endif

    fclose(ptr_image_file);

    return 0;
}

int
main(void)
{
// NOTE/BUG: this is blown away with the call to get_image_data
#if 0
    uint16_t *image_ptr = malloc((sizeof *image_ptr) * MAX_ROW * MAX_COL);
#else
    uint16_t *image_ptr;
#endif

    // Get Image Data
    image_ptr = get_image_data(1);

    int row,
     col,
     pixel_index = 0;

// NOTE/BUG: this uses the global variable image which has no data
// NOTE/BUG: for loops make access very cache intensive (i.e. slow)
// NOTE/BUG: what transform are you trying to do?
#if 0
    for (col = 0; col < MAX_COL; col++) {
        for (row = 0; row < MAX_ROW; row++) {
// NOTE/BUG: wrong way to index
            *(*(image + col) + row) = *(image_ptr + pixel_index);
            pixel_index++;
        }
    }
#else
    for (row = 0; row < MAX_ROW; row++) {
        for (col = 0; col < MAX_COL; col++) {
            image_ptr[(row * MAX_COL) + col] += pixel_index;
            pixel_index++;
        }
    }
#endif

#if 0
    save_image();
#else
    save_image(image_ptr);
    free(image_ptr);
#endif

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM