If you want to use set_value for a specific field, you need to have a validation rule for that field. No validation rule makes set_value return NULL (or an empty string I have not checked which)
In my controller I added
$this->form_validation->set_rules('gender','Gender','required');
before my form_validation->run line. I could then used your syntax:
<?php echo form_dropdown('gender', $gender, set_value('gender')); ?>
I found set_value() worked, NOT set_select(). Remember you can add a second parameter to set_value to have a default of male or female which is used if the form has not yet been validated. I extract the existing value from my backend database, and pass this in as such:
<?php echo form_dropdown('gender', $gender, set_value('gender',$persons_gender_from_db)); ?>
Note also that set value returns the index of the array of options('M' or 'F'), not the displayed value ('Male' or 'Female'). For lists containing more options that two genders, I use the primary key of the database table containing the options, to ensure uniqueness.
Although I wonder when I will first be asked to add 'Other' to the list of choices for gender....