[英]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*int
而size_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.