繁体   English   中英

使用memset初始化三值结构数组

[英]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函数

  1. memset函数将c的值(转换为unsigned char复制到s指向的对象的前n 字符中的每个字符中。

转换为unsigned char ”,因此它设置字节。

还请考虑以下几点:

  1. 不需要malloc()的返回值,如果不这样做,则更好。

  2. 始终检查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);
  1. 您传递指针的地址而不是指针cArray的值。
  2. 您只传递单个color结构的大小。 此大小超出了指针的大小,因此导致崩溃。 如果要设置整个数组,则应将大小存储到一个临时变量中。
  3. 您传递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.

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