[英]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.