Fix Python HAL device creation params only last one used (#24812)

While using the Python bindings for the IREE runtime, I noticed that
only the last key-value pair in the dictionary passed as the `params`
argument to HalDriver's `create_device` method is actually consumed.

In the code below, pointers created using `c_str()` from the elements of
`param_strings` are stored in `passed_params`, but the issue is that if
`param_strings` is reallocated, those pointers become invalid.


https://github.com/iree-org/iree/blob/3c2a79f36e8b3333ffebb55c4afef1798581ccb5/runtime/bindings/python/hal.cc#L1133-L1145

In this PR, prevent reallocation by reserving the necessary space for
`param_strings` in advance.

Signed-off-by: Shogo Yamazaki <pgp@mocknen.net>
diff --git a/runtime/bindings/python/hal.cc b/runtime/bindings/python/hal.cc
index e19c857..d6d7a91 100644
--- a/runtime/bindings/python/hal.cc
+++ b/runtime/bindings/python/hal.cc
@@ -1133,9 +1133,11 @@
   std::vector<std::pair<std::string, std::string>> param_strings;
   std::vector<iree_string_pair_t> passed_params;
   if (params.has_value()) {
-    for (auto it : params.value()) {
-      param_strings.push_back(std::make_pair(py::cast<std::string>(it.first),
-                                             py::cast<std::string>(it.second)));
+    auto params_dict = params.value();
+    param_strings.reserve(py::len(params_dict));
+    for (auto it : params_dict) {
+      param_strings.emplace_back(py::cast<std::string>(it.first),
+                                 py::cast<std::string>(it.second));
       passed_params.push_back(
           iree_string_pair_t{{{param_strings.back().first.c_str(),
                                param_strings.back().first.size()}},