Search is not an archive.
You can check it by seeing _post_type_archive docs, you'll see that it:
You need to checks whether the query is for an archive page of a given post type(s).
Using this condition in your pre_get_posts, then it won't affect search results at all.
Secondly this meta_query shows that you are looking to get only posts that have this meta value set and different than out of stock, so it will exclude all posts and pages (because they don't have such meta value at all).
$q->set( 'meta_query', array(array(
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => 'NOT IN'
)));
add_action( 'pre_get_posts', 'hide_out_of_stock_from_search' );
function hide_out_of_stock_from_search( $q ) {
if ( ! is_admin() && $q->is_main_query() && $q->is_search() ) {
$q->set( 'meta_query', array(
'relation' => 'OR',
array(
'key' => '_stock_status',
'value' => 'outofstock',
'compare' => 'NOT IN'
),
array(
'key' => '_stock_status',
'compare' => 'NOT EXISTS'
)
));
}
}