[英]Initialize array of 3-value structures using memset
How do I initialize array of structures with values? 如何使用值初始化结构数组? So, I have structure color with rgb values.
因此,我具有带有rgb值的结构颜色。
struct color{
GLfloat r;
GLfloat g;
GLfloat b;
}
and trying to initialize it with 1.0f. 并尝试使用1.0f对其进行初始化。
color* cArray = (color*) malloc(w*h*sizeof(color));
memset(&cArray, 1.0, sizeof color);
But instead of correct work I get segmentation fault on cArray[0]. 但是我没有正确的工作,而是在cArray [0]上遇到了分段错误。 What do I miss?
我想念什么?
Note: Do not cast void *
(result of malloc()
) to other pointers and always check the result of malloc()
& friends . 注意:请勿将
void *
( malloc()
结果) malloc()
为其他指针,并始终检查malloc()
和friends的结果 。
Memset takes an unsigned char (most likely 8 bits) and treats the area passed as an array of char. Memset接受一个无符号的char(最有可能是8位),并将通过的区域视为char数组。 It has no idea of structs, arrays etc. Just of a 1-dimensional array of char.
它不知道结构,数组等。只是char的一维数组。 (as @chqrlie noted,
memset()
actually takes an int
; this is, however, internally converted to unsigned char
). (正如@chqrlie所指出的,
memset()
实际上是一个int
;但是,它在内部转换为unsigned char
)。
The segfault is because you pass the address of cArray
which is a pointer to the actual array, not its value which would be the array itself. segfault是因为您传递了
cArray
的地址,该地址是指向实际数组的指针,而不是其值(该值将是数组本身)。
For float, memset() most likely only makes sense setting it to all- 0
: 对于float,memset()最有可能仅将其设置为all-
0
才有意义:
memset(cArray, 0, sizeof(struct color) * w * h);
Note: memset has no idea on data types. 注意:memset对数据类型一无所知。 It just takes a pointer to a block of memory and a count and stores the value to that area.
它只需要指向一个内存块和一个计数的指针,并将值存储到该区域。 It is your responsibility all arguments are valid!
所有论据均有效,这是您的责任!
Note that writing the memory area with 0
is actually float zero ( 0.0
, actually +0.0
), as that has all bits cleared. 请注意,用
0
写入存储区实际上是浮点数零( 0.0
,实际上是+0.0
),因为它清除了所有位。 That was a briliant intention by the guys who dsigned the encoding for floats. 对浮点数进行编码的家伙们的意图很强烈。
As you allocate right before, you can combine this using calloc()
. 如前所述,您可以使用
calloc()
将其合并。 That will allocate and clear the memory area of the array. 这将分配并清除阵列的内存区域。 However, if you intend to set all values explicitly anyway, you better stick with
malloc()
. 但是,如果打算以任何方式显式设置所有值,则最好坚持使用
malloc()
。
If you want to set other float values, you have to write your own loop. 如果要设置其他浮点值,则必须编写自己的循环。 However, you can threat the array as 1-dimensional for that.
但是,您可以为此威胁数组为一维数组。
for ( size_t i = 0 ; i < w * h ; i++ )
cArray[i] = (struct color){ .r = 1.0, .g = 1.0, .b = 1.0 };
That uses a compound literal . 那使用复合文字 。 Alternatively you can also set the fields seperately.
另外,您也可以单独设置字段。
If you are upt for speed, the compount-literal approach might be the fastest. 如果您追求速度,那么复合文字方法可能是最快的。 This way ,the compiler might very well load al values into three registers and store them directly into memory using store-multiple.
这样,编译器很可能将al值加载到三个寄存器中,并使用store-multiple将它们直接存储到内存中。 However it might do, I would bet the compiler will recognize that pattern and optimize as hell, as it is commonly used for very large loops.
无论如何,我敢打赌,编译器将识别出该模式并进行优化,因为它通常用于非常大的循环。
You can't use memset()
to set float
values. 您不能使用
memset()
设置float
值。
The memset()
function is used for bytes, so using it for float
s is not allowed, you need to explicitly initialize each member memset()
函数用于字节,因此不允许将其用于float
,您需要显式初始化每个成员
This is memset()
's signature 这是
memset()
的签名
void *memset(void *s, int c, size_t n);
although it expects int
1 for it's second parameter, the standard says 尽管它的第二个参数是
int
1 ,但标准表示
7.24.6 Miscellaneous functions
7.24.6其他功能
7.24.6.1 The
memset
function7.24.6.1
memset
函数
- The
memset
function copies the value ofc
(converted to anunsigned char
) into each of the firstn
characters of the object pointed to bys
.memset
函数将c
的值(转换为unsigned char
)复制到s
指向的对象的前n
字符中的每个字符中。
" converted to an unsigned char
" so it sets bytes. “ 转换为
unsigned char
”,因此它设置字节。
Also take in consideration the following: 还请考虑以下几点:
You don't need to cast the return value of malloc()
, and it's better if you don't do it. 您不需要
malloc()
的返回值,如果不这样做,则更好。
Always check that malloc()
returned non- NULL
, specially when allocating a lot of memory. 始终检查
malloc()
返回非NULL
,尤其是在分配大量内存时。
1 As you can see you can't pass float. 1 如您所见,您不能通过浮点数。
There are multiple problems with your code: 您的代码有多个问题:
You allocate a matrix w
x h
of color
structures: 您分配
color
结构的矩阵w
x h
:
color *cArray = (color*) malloc(w * h * sizeof(color));
The cast is not necessary in C, but opinions differ about the recommended alternatives. 在C语言中,强制转换不是必需的,但是对于推荐的替代方案,意见不一。 A safer version would be:
一个更安全的版本是:
color *cArray = malloc(w * h * sizeof(*cArray));
More importantly, our call to memset
is incorrect in multiple ways: 更重要的是,我们对
memset
的调用在许多方面都是错误的:
memset(&cArray, 1.0, sizeof color);
cArray
. cArray
的值。 color
structure. color
结构的大小。 This size exceeds the size of the pointer, hence the crash. double
instead of an int as the value to set. double
精度值而不是整数作为要设置的值。 You cannot initialize an array of double
values with memset
: this function initializes a block of memory by setting all bytes to the same value. memset
初始化一个double
memset
值数组:此函数通过将所有字节设置为相同值来初始化内存块。 Passing 0
would initialize double
values correctly if your system uses IEEE-754 representation for floating point values, otherwise it might invoke undefined behaviour. 0
将正确初始化double
精度值,否则,它可能会调用未定义的行为。 You must initialize the matrix with a loop: 您必须使用循环初始化矩阵:
for (size_t i = 0, n = w * h; i < n; i++) {
cArray[i].r = cArray[i].g = cArray[i].b = 1.0;
}
This loop can be optimized by modern compilers. 可以通过现代编译器优化此循环。 I suggest you play with this very interesting tool: http://gcc.godbolt.org/# .
我建议您使用这个非常有趣的工具: http : //gcc.godbolt.org/# 。
You can also keep a copy of a pre-initialized array and use memcpy
to initialize the allocated array. 您还可以保留一个预初始化数组的副本,并使用
memcpy
初始化分配的数组。
First, colors are (in your case) 3 bytes, not 3 floats. 首先,(在您的情况下)颜色是3个字节,而不是3个浮点数。
then this code: 然后这段代码:
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);
will cause a compiler to raise several warnings: 将导致编译器发出以下警告:
due to the compiler will not knowing what a 'color' is due to: 由于编译器将不知道什么是“颜色”,原因是:
syntax errors in the struct definition
and references to the struct are missing the 'struct' modifier.
when calling malloc() (and family of functions) always check (!=NULL) the returned value to assure the operation was successful. 调用malloc()(和函数系列)时,请始终检查(!= NULL)返回值以确保操作成功。
In C, do not cast the returned value from malloc() (and family of functions) 在C语言中,请勿转换malloc()(和函数族)的返回值
notice that a struct definition ends with a ';' 注意,结构定义以“;”结尾
suggest using: 建议使用:
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) );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.