2013-11-28 4 views
1

Следующий код является многопоточным и работает для потока id = 0 и 1 одновременно.Структура структуры памяти в многопоточном коде

typedef struct 
{ 
    unsigned char pixels[4]; 
} FourPixels; 

main() 

{ 

    FourPixels spixels[]; 


    //copy on spixels 
    spixels[id] = gpixels[id]; 

    //example : remove blue component 
    spixels[id].pixels[0] &= 0xFC; 
    spixels[id].pixels[1] &= 0xFC; 
    spixels[id].pixels[2] &= 0xFC; 
    spixels[id].pixels[3] &= 0xFC; 

} 

Мы видим, что идентификатор потока = 0 выбирает 4 символов, и идентификатор потока = 1 выбирает другой набор из 4 символов.

Я хочу знать в памяти, как создаются строения скрепки [0] и spixles [1], что-то вроде этого?

spixels[0]          spixels[1]     
pixel[0] pixel[1] pixel[2] pixel[3]  pixel[0] pixel[1] pixel[2] pixel[3] 
2000  2001 2002  2003   2004  2005  2006  2007 

Вопрос заключается в spixel [0] и spixel [1] помещен смежно с гарантией, как показано выше?

ответ

0

Массив гарантируется тем, что стандарт должен быть смежным. Это также гарантирует, что первая запись будет на низком адреса в памяти, а следующий будет на более высокий и т.д.

В случае структуры pixel массив, pixel[1] всегда будет непосредственно после pixel[0]. То же самое со следующими записями.

+0

, но они не могут видеть плеча [0] и spixel [1]. они рассматриваются одновременно. – gpuguy

+0

@gpuguy: «Работа с одновременно» не влияет на распределение памяти (которое не показано в вашем коде выше). –

+0

@gpuguy Да, это гарантировано. Все записи массива смежны независимо от типа массива. –

0

Да, массивы размещены в смежной памяти. Это разрешить арифметику указателя.

1

Да, они будут изложены смежно, как вы говорите. Теперь, вероятно, кто-то придет и скажет, что он не гарантируется на всех платформах, потому что выравнивание структуры может быть больше, чем его размер, поэтому у вас может быть разрыв между двумя «телами» структуры из-за неявного заполнения после первого один. Но неважно, потому что выравнивание любого разумного компилятора и платформы будет всего 1 байт (как в char).

Если бы я писал код, который полагался на это, я бы добавил утверждение времени компиляции, что размер двух из этих структур должен быть ровно 8 байтов, а затем я был бы на 100% уверен.

Edit: вот пример того, как проверка времени компиляции может работать:

struct check { 
    char floor[sizeof(FourPixels[2]) - 8]; 
    char ceiling[8 - sizeof(FourPixels[2])]; 
}; 

Идея заключается в том, что если размер не 8, один из массивов будет иметь отрицательный размер. Если это 8, они оба будут иметь нулевой размер. Обратите внимание, что это расширение компилятора (например, GCC поддерживает массивы нулевой длины), поэтому вы можете искать лучший способ. Я больше человек на C++, и у нас есть причудливые трюки для этого (в C++ 11 он встроен: static_assert()).

+0

Не могли бы вы продемонстрировать утверждение времени компиляции – gpuguy

+0

Конечно, я добавил что-то. Это может быть не идеально, но я думаю, что это иллюстрирует эту идею. –

Смежные вопросы