[英]Initialize array of 3-value structures using memset
如何使用值初始化结构数组? 因此,我具有带有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]上遇到了分段错误。 我想念什么?
注意:请勿将void *
( malloc()
结果) malloc()
为其他指针,并始终检查malloc()
和friends的结果 。
Memset接受一个无符号的char(最有可能是8位),并将通过的区域视为char数组。 它不知道结构,数组等。只是char的一维数组。 (正如@chqrlie所指出的, memset()
实际上是一个int
;但是,它在内部转换为unsigned char
)。
segfault是因为您传递了cArray
的地址,该地址是指向实际数组的指针,而不是其值(该值将是数组本身)。
对于float,memset()最有可能仅将其设置为all- 0
才有意义:
memset(cArray, 0, sizeof(struct color) * w * h);
注意:memset对数据类型一无所知。 它只需要指向一个内存块和一个计数的指针,并将值存储到该区域。 所有论据均有效,这是您的责任!
请注意,用0
写入存储区实际上是浮点数零( 0.0
,实际上是+0.0
),因为它清除了所有位。 对浮点数进行编码的家伙们的意图很强烈。
如前所述,您可以使用calloc()
将其合并。 这将分配并清除阵列的内存区域。 但是,如果打算以任何方式显式设置所有值,则最好坚持使用malloc()
。
如果要设置其他浮点值,则必须编写自己的循环。 但是,您可以为此威胁数组为一维数组。
for ( size_t i = 0 ; i < w * h ; i++ )
cArray[i] = (struct color){ .r = 1.0, .g = 1.0, .b = 1.0 };
那使用复合文字 。 另外,您也可以单独设置字段。
如果您追求速度,那么复合文字方法可能是最快的。 这样,编译器很可能将al值加载到三个寄存器中,并使用store-multiple将它们直接存储到内存中。 无论如何,我敢打赌,编译器将识别出该模式并进行优化,因为它通常用于非常大的循环。
您不能使用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
)复制到s
指向的对象的前n
字符中的每个字符中。
“ 转换为unsigned char
”,因此它设置字节。
还请考虑以下几点:
您不需要malloc()
的返回值,如果不这样做,则更好。
始终检查malloc()
返回非NULL
,尤其是在分配大量内存时。
1 如您所见,您不能通过浮点数。
您的代码有多个问题:
您分配color
结构的矩阵w
x h
:
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
精度值而不是整数作为要设置的值。 您不能使用memset
初始化一个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个字节,而不是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);
将导致编译器发出以下警告:
由于编译器将不知道什么是“颜色”,原因是:
syntax errors in the struct definition
and references to the struct are missing the 'struct' modifier.
调用malloc()(和函数系列)时,请始终检查(!= NULL)返回值以确保操作成功。
在C语言中,请勿转换malloc()(和函数族)的返回值
注意,结构定义以“;”结尾
建议使用:
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.