简体   繁体   English

C中动态分配二维结构数组

[英]Dynamically allocate 2-dimensional structure array in C

I have been trying to create an edges filter as per CS50 problem set 4. I have seen several solutions, however I would like to know if my approach can work.我一直在尝试根据 CS50 问题集 4 创建一个边缘过滤器。我已经看到了几种解决方案,但是我想知道我的方法是否可行。 I'm trying to expand the input image by a black border of one pixel width.我正在尝试通过一个像素宽度的黑色边框来扩展输入图像。 For this I want to expand my two-dimensional RGBTRIPLE structure by one pixel on either side.为此,我想将我的二维 RGBTRIPLE 结构在任一侧扩展一个像素。 I am setting all values of RGB to 0 (aka black) in the first line and then copy the original image into the temporary structure, substituting all except the border values with the respective colours.我在第一行将 RGB 的所有值设置为 0(又名黑色),然后将原始图像复制到临时结构中,用各自的颜色替换除边框值之外的所有值。

I am defining a variable-length two-dimensional structure RGBTRIPLE which contains three values of the datatype BYTE:我正在定义一个可变长度的二维结构 RGBTRIPLE,其中包含数据类型 BYTE 的三个值:

RGBTRIPLE temp[height+2][width+2] = {};

I'm getting the error message that because of the variable length it may not have been initialized, which I understand.我收到错误消息,由于长度可变,它可能尚未初始化,我理解。 I have seen several solutions using pointers and malloc , which I hopefully implemented correctly in the first line.我已经看到了几种使用指针和malloc的解决方案,我希望在第一行中正确实现了这些解决方案。 I have been trying to connect the RGBTRIPLE to the pointer as per the following two lines:我一直在尝试按照以下两行将 RGBTRIPLE 连接到指针:

RGBTRIPLE *ptr = (RGBTRIPLE *)malloc((height+2)*(width+2)*sizeof(RGBTRIPLE));
RGBTRIPLE temp[height+2][width+2] = &ptr;
temp[height+2][width+2] = {0};

Setting all the values to zero here does also not work, but that's another issue.在这里将所有值设置为零也不起作用,但这是另一个问题。

I want to use the original RGBTRIPLE in a for-loop and I cannot get this to work.我想在for 循环中使用原始的 RGBTRIPLE,但我无法让它工作。 All examples I have seen use the pointers afterwards to add any information.我看到的所有示例都在之后使用指针来添加任何信息。 Is there any way to define the RGBTRIPLE using malloc so that I can afterwards use it in code as a "normal" element of the structure as seen with temp[][] :有什么方法可以使用 malloc 定义 RGBTRIPLE,以便之后我可以在代码中将其用作结构的“正常”元素,如temp[][]所示:

for(int i = 0; i < height; i++)
{
    for(int j = 0; j < width; j++)
    {
        temp[i+1][j+1] = image[i][j];
    }
}

for(int i = 1; i <= height; i++)
{
    for(int j = 1; j <= width; j++)
    {
        int counter = 0;
        float gxr, gxb, gxg, gyr, gyb, gyg = 0;

        //right pixel
        gxb += (2*temp[i][j+1].rgbtBlue);
        gxg += (2*temp[i][j+1].rgbtGreen);
        gxr += (2*temp[i][j+1].rgbtRed);

etc. for all surrounding pixels.等所有周围的像素。

Any help is appreciated.任何帮助表示赞赏。

You might initialize as in the following sample code.您可以按照以下示例代码进行初始化。

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

typedef unsigned char BYTE;

typedef struct tagRGBTRIPLE
{
    BYTE rgbtBlue;
    BYTE rgbtGreen;
    BYTE rgbtRed;
} RGBTRIPLE;

int main()
{
    int height = 400;
    int width  = 600;

    RGBTRIPLE img[height][width];
    RGBTRIPLE temp[height+2][width+2];

    for (int i = 0; i < height; i++)                /* Build a sample image file */
    {
        for (int j = 0; j < width; j++)
        {
            img[i][j].rgbtRed   = 68;
            img[i][j].rgbtGreen = 188;
            img[i][j].rgbtBlue  = 32;
        }
    }

    for (int i = 0; i < (height + 2); i++)          /* Initialize the temporary RGBTRIPLE structure*/
        for (int j = 0; j < (width + 2); j++)
        {
            temp[i][j].rgbtRed   = 0;
            temp[i][j].rgbtGreen = 0;
            temp[i][j].rgbtBlue  = 0;
        }

    for(int i = 0; i < height; i++)                 /* Imported code from the issue */
    {
        for(int j = 0; j < width; j++)
        {
            temp[i+1][j+1] = img[i][j];
        }
    }

    for(int i = 0; i <= (height + 2); i++)          /* Right and left edges*/
    {
        float gxr = 0, gxb = 0, gxg = 0;

        temp[i][0].rgbtRed   = gxr;
        temp[i][0].rgbtGreen = gxg;
        temp[i][0].rgbtBlue  = gxb;
        temp[i][width + 1].rgbtRed   = gxr;
        temp[i][width + 1].rgbtGreen = gxg;
        temp[i][width + 1].rgbtBlue  = gxb;
    }

    for(int i = 0; i <= (width + 2); i++)           /* Top and bottom edges */
    {
        float gyr = 0, gyb = 0, gyg = 0;

        temp[0][i].rgbtRed   = gyr;
        temp[0][i].rgbtGreen = gyg;
        temp[0][i].rgbtBlue  = gyb;
        temp[height + 1][i].rgbtRed   = gyr;
        temp[height + 1][i].rgbtGreen = gyg;
        temp[height + 1][i].rgbtBlue  = gyb;
    }

    /* See what we have at a pixel point */

    printf("Top edge RGBTRIPLE %d, %d, %d \n", temp[0][144].rgbtRed, temp[0][144].rgbtGreen, temp[0][144].rgbtBlue);
    printf("Left edge RGBTRIPLE %d, %d, %d \n", temp[144][0].rgbtRed, temp[144][0].rgbtGreen, temp[144][0].rgbtBlue);
    printf("RGBTRIPLE within image %d, %d, %d \n", temp[144][144].rgbtRed, temp[144][144].rgbtGreen, temp[144][144].rgbtBlue);

    return 0;
}

C does not really provide a simple way to initialize tuples so you probably would need "for" loops to do this. C 并没有真正提供初始化元组的简单方法,因此您可能需要“for”循环来执行此操作。 Experiment with this scenario and see if it applies to the spirit of your project.试验一下这个场景,看看它是否适用于你的项目精神。

Some issues:一些问题:

Use mem...() where possible.尽可能使用mem...()

To zero byte fill an entire variable length array :零字节填充整个可变长度数组

// RGBTRIPLE temp[height+2][width+2] = {};
RGBTRIPLE temp[height+2][width+2];
memset(temp, 0, sizeof temp);

I am setting all values of RGB to 0 (aka black) in the first line and then copy the original image into the temporary structure, substituting all except the border values with the respective colours.我在第一行将 RGB 的所有值设置为 0(又名黑色),然后将原始图像复制到临时结构中,用各自的颜色替换除边框值之外的所有值。

Alternative:选择:

// Given image[][] is a 2D array 
for(int i = 0; i < height; i++) {
  memcpy(temp[i+1], image[i], sizeof image[i]);
}

Initialize properly正确初始化

float gxr, gxb, gxg, gyr, gyb, gyg = 0; only initializes gyg .只初始化gyg

float gxr = 0;
float gxb = 0;
...
float gyg = 0;

Advanced: int math vs. size_t math高级: int数学与size_t数学

int*int*size_t may overflow int*int where size_t*int*int does not. int*int*size_t可能会溢出int*intsize_t*int*int不会溢出。

Cast not needed in C. C 中不需要铸造。

Size to the referenced object, not the type.大小为引用的 object,而不是类型。

// RGBTRIPLE *ptr = (RGBTRIPLE *)malloc((height+2)*(width+2)*sizeof(RGBTRIPLE));
RGBTRIPLE *ptr = malloc(sizeof ptr[0] * (height+2) * (width+2));

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

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