如何使用值初始化结构数组? 所以,我有rgb值的结构颜色。
struct color{
GLfloat r;
GLfloat g;
GLfloat b;
}
并尝试使用1.0f初始化它。
color* cArray = (color*) malloc(w*h*sizeof(color));
memset(&cArray, 1.0, sizeof color);
但是我没有正确的工作,而是在cArray [0]上得到了分段错误。 我错过了什么?
答案 0 :(得分:3)
注意:请勿将void *
(malloc()
的结果)投射到其他指针,始终检查malloc()
&的结果朋友强>
Memset采用unsigned char(最可能是8位)并将传递的区域视为char数组。它不知道结构,数组等。只是一维的char数组。 (正如@chqrlie指出的那样,memset()
实际上需要int
;但是,这会在内部转换为unsigned char
)。
段错误是因为你传递了cArray
的地址,它是一个指向实际数组的指针,而不是它的数值本身的值。
对于float,memset()最有可能只设置为全部 - 0
:
memset(cArray, 0, sizeof(struct color) * w * h);
注意:memset对数据类型一无所知。它只需要一个指向内存块和计数的指针,并将值存储到该区域。 你的责任所有参数都有效!
请注意,使用0
写入内存区域实际上是浮点零(0.0
,实际上是+0.0
),因为它清除了所有位。这是那些为浮点数设计编码的人的明智意图。
如前所述,您可以使用calloc()
进行组合。这将分配和清除阵列的内存区域。但是,如果您打算明确设置所有值,最好坚持使用malloc()
。
如果要设置其他浮点值,则必须编写自己的循环。但是,您可以将阵列威胁为1维。
for ( size_t i = 0 ; i < w * h ; i++ )
cArray[i] = (struct color){ .r = 1.0, .g = 1.0, .b = 1.0 };
使用复合文字。或者,您也可以单独设置字段。
如果你想要速度,那么compount-literal方法可能是最快的。这样,编译器可以很好地将al值加载到三个寄存器中,并使用store-multiple将它们直接存储到内存中。不过它可能会这样做,我敢打赌编译器会认识到这种模式并优化为地狱,因为它通常用于非常大的循环。
答案 1 :(得分:2)
您无法使用memset()
设置float
值。
memset()
函数用于字节,因此不允许将其用于float
,您需要显式初始化每个成员
这是memset()
的签名
void *memset(void *s, int c, size_t n);
虽然它的第二个参数需要int
1 ,但标准说
7.24.6其他功能
7.24.6.1
memset
功能
- 醇>
memset
功能会将c
(转换为unsigned char
)的值复制到每个首个n
字符中1}}指向的对象。
&#34; 转换为s
&#34;所以它设置了字节。
还要考虑以下因素:
你don't need to cast the return value of malloc()
,如果你不这样做会更好。
请务必检查unsigned char
是否返回非malloc()
,特别是在分配大量内存时。
1 正如您所见,您无法通过浮动。
答案 2 :(得分:2)
您的代码存在多个问题:
您分配了w
x h
个color
结构的矩阵:
color *cArray = (color*) malloc(w * h * sizeof(color));
C中没有必要使用演员表,但对推荐的替代方案的看法不同。更安全的版本是:
color *cArray = malloc(w * h * sizeof(*cArray));
更重要的是,我们对memset
的调用在多个方面都是错误的:
memset(&cArray, 1.0, sizeof color);
cArray
的值。color
结构的大小。此大小超过指针的大小,因此崩溃。如果您打算设置整个数组,则应将大小存储到临时变量中。double
而不是int作为要设置的值。您无法使用double
初始化memset
值数组:此函数通过将所有字节设置为相同值来初始化内存块。如果您的系统使用IEEE-754表示形式表示浮点值,则传递0
将正确初始化double
值,否则可能会调用未定义的行为。您必须使用循环初始化矩阵:
for (size_t i = 0, n = w * h; i < n; i++) {
cArray[i].r = cArray[i].g = cArray[i].b = 1.0;
}
这个循环可以通过现代编译器进行优化。我建议你玩这个非常有趣的工具:http://gcc.godbolt.org/#。
您还可以保留预初始化数组的副本,并使用memcpy
初始化已分配的数组。
答案 3 :(得分:-2)
首先,颜色是(在你的情况下)3个字节,而不是3个浮点数。
然后这段代码:
struct color{
GLfloat r;
GLfloat g;
GLfloat b;
}
and trying to initialize it with 1.0f.
color* cArray = (color*) malloc(w*h*sizeof(color));
memset(&cArray, 1.0, sizeof color);
会导致编译器发出几个警告:
由于编译器不知道什么是&#39;颜色&#39;是由于:syntax errors in the struct definition
and references to the struct are missing the 'struct' modifier.
当调用malloc()(和函数族)时,总是检查(!= NULL)返回的值以确保操作成功。
在C中,不要从malloc()(和函数族)转换返回的值
请注意,结构定义以&#39 ;;&#39;
结尾建议使用:
struct color
{
char r;
char g;
char b;
};
struct color* cArray = NULL;
if( NULL == (cArray =malloc(w*h*sizeof(struct color))))
{ // then malloc failed
perror( "malloc for struct color array failed" );
exit( EXIT_FAILURE )
}
// implied else, malloc successful
memset(&cArray, 1, w*h*(sizeof (struct color) );