簡體   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