Значения массива перечислений Memset установлены неправильно (C/C++)

Я пытаюсь использовать memset для установки всех значений в массиве enum в одно значение, но я не вижу правильных результатов. Первый мемсет работает, второй нет. Мой код:

// definitions
#define NUM_THREADS     1

enum ThreadState
{
    INITIALIZING,
    READY_TO_CALCULATE,
    CALCULATED,
    READY_TO_UPDATE,
    UPDATED
};


// Later on, in the code...
ThreadState Thread_States[NUM_THREADS];

// Somehow this works - after this statement, every entry in Thread_States is INITIALIZING
memset(Thread_States, INITIALIZING, NUM_THREADS* sizeof(ThreadState));

// ... later on (or even immediately right after) ...

// Failure - after this statement, every entry in Thread_States is 16843009
memset(Thread_States, READY_TO_CALCULATE, NUM_THREADS* sizeof(ThreadState));

Как поясняется в комментариях, при первом вызове memset значения устанавливаются такими, какие я ожидал (ИНИЦИАЛИЗАЦИЯ, т. е. 0). Когда я запускаю второй оператор, я не вижу значений, установленных в READY_TO_CALCULATE (т. е. 1). Скорее, они установлены на 16843009, когда я проверяю отладчик.

Есть ли причина, по которой это относительно простое использование memset непоследовательно в своем поведении?

Спасибо.


person user3236291    schedule 25.01.2014    source источник
comment
Перечисление sizeof() имеет тип int, а не char.   -  person brian beuning    schedule 26.01.2014
comment
Представьте, что тип данных для вашего перечисления составляет 4 байта, memset устанавливает каждое значение в 0x02020202, возможно, это не то, что вам нужно.   -  person Retired Ninja    schedule 26.01.2014


Ответы (2)


Функция memset присваивает каждому байту памяти второй аргумент (после усечения второго аргумента). Поскольку перечисления (обычно) имеют размер int, вы получите неверный результат. Единственный раз, когда он будет работать, это для значения перечисления, равного нулю, так как тогда он установит все байты равными нулю.

Если вы используете, например. READY_TO_CALCULATE вы установите для каждого байта значение 1, что создаст int значений 0x01010101 вместо 0x00000001.

person Some programmer dude    schedule 25.01.2014
comment
Это также будет работать для -1. Так как он будет устанавливать каждый байт как ff, а ffffffff также равно -1 - person DollarAkshay; 26.05.2019
comment
@DollarAkshay Я думаю, что C и C ++ различаются в этом отношении. IIRC C еще не требует представления отрицательных чисел с дополнением до двух, но C ++ требует. И это помимо того, что -1 не так легко понять с первого взгляда, как 0xff. - person Some programmer dude; 19.03.2021

Ваш вопрос C или C++?

В случае C не забудьте перебрать массив, чтобы установить каждое значение, поскольку memset просто не предназначен для такого рода функций. Вы пытаетесь установить элементы, а не память.

В случае C++ используйте класс перечисления для состояния. Кроме того, попробуйте инкапсулировать состояние вашего потока в его собственном классе, который им управляет, и заставьте инициализатор по умолчанию построить его правильно.

person dascandy    schedule 04.01.2016