使用memset初始化3值结构的数组

时间:2015-06-05 21:13:51

标签: c arrays opengl memory 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]上得到了分段错误。 我错过了什么?

4 个答案:

答案 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功能

     
      
  1. memset功能会将c (转换为unsigned char的值复制到每个首个n 字符中
  2.   

&#34; 转换为s &#34;所以它设置了字节。

还要考虑以下因素:

  1. don't need to cast the return value of malloc(),如果你不这样做会更好。

  2. 请务必检查unsigned char是否返回非malloc(),特别是在分配大量内存时。

  3. 1 正如您所见,您无法通过浮动。

答案 2 :(得分:2)

您的代码存在多个问题:

您分配了w x hcolor结构的矩阵:

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而不是int作为要设置的值。您无法使用double初始化memset值数组:此函数通过将所有字节设置为相同值来初始化内存块。如果您的系统使用IEEE-754表示形式表示浮点值,则传递0将正确初始化double值,否则可能会调用未定义的行为。
  4. 您必须使用循环初始化矩阵:

    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) );