diff --git a/mex/sources/bytecode/ErrorHandling.hh b/mex/sources/bytecode/ErrorHandling.hh
index 43498a57945260a5769dd7b4e2845be550130c0d..bd11046907251114ba454ecab4b17eb4c1fc9c82 100644
--- a/mex/sources/bytecode/ErrorHandling.hh
+++ b/mex/sources/bytecode/ErrorHandling.hh
@@ -37,12 +37,6 @@
 #define BYTE_CODE
 #include "CodeInterpreter.hh"
 
-#ifdef OCTAVE_MEX_FILE
-# define CHAR_LENGTH 1
-#else
-# define CHAR_LENGTH 2
-#endif
-
 using namespace std;
 
 constexpr int NO_ERROR_ON_EXIT = 0, ERROR_ON_EXIT = 1;
@@ -192,9 +186,8 @@ public:
 
   ExpressionType EQN_type;
   it_code_type it_code_expr;
-  size_t nb_endo, nb_exo, nb_param;
-  char *P_endo_names, *P_exo_names, *P_param_names;
-  size_t endo_name_length, exo_name_length, param_name_length;
+  size_t endo_name_length; // Maximum length of endogenous names
+  vector<string> P_endo_names, P_exo_names, P_param_names;
   unsigned int EQN_equation, EQN_block, EQN_block_number;
   unsigned int EQN_dvar1, EQN_dvar2, EQN_dvar3;
   vector<tuple<string, SymbolType, unsigned int>> Variable_list;
@@ -205,42 +198,33 @@ public:
     mxArray *M_ = mexGetVariable("global", "M_");
     if (!M_)
       mexErrMsgTxt("Can't find global variable M_");
-    if (mxGetFieldNumber(M_, "endo_names") == -1)
-      {
-        nb_endo = 0;
-        endo_name_length = 0;
-        P_endo_names = nullptr;
-      }
-    else
-      {
-        nb_endo = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names")));
-        endo_name_length = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names")));
-        P_endo_names = reinterpret_cast<char *>(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "endo_names"))));
-      }
-    if (mxGetFieldNumber(M_, "exo_names") == -1)
-      {
-        nb_exo = 0;
-        exo_name_length = 0;
-        P_exo_names = nullptr;
-      }
-    else
-      {
-        nb_exo = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "exo_names")));
-        exo_name_length = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "exo_names")));
-        P_exo_names = reinterpret_cast<char *>(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "exo_names"))));
-      }
-    if (mxGetFieldNumber(M_, "param_names") == -1)
-      {
-        nb_param = 0;
-        param_name_length = 0;
-        P_param_names = nullptr;
-      }
-    else
-      {
-        nb_param = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names")));
-        param_name_length = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names")));
-        P_param_names = reinterpret_cast<char *>(mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names"))));
-      }
+
+    auto get_field_names = [&](const char *symbol_type)
+    {
+      vector<string> r;
+      if (mxGetFieldNumber(M_, symbol_type) != -1)
+        {
+          auto M_field = mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, symbol_type));
+          if (!mxIsCell(M_field))
+            mexErrMsgTxt((string{"M_."} + symbol_type + " is not a cell array").c_str());
+          for (size_t i = 0; i < mxGetNumberOfElements(M_field); i++)
+            {
+              const mxArray *cell_mx = mxGetCell(M_field, i);
+              if (!(cell_mx && mxIsChar(cell_mx)))
+                mexErrMsgTxt((string{"M_."} + symbol_type + " contains a cell which is not a character array").c_str());
+              r.emplace_back(mxArrayToString(cell_mx));
+            }
+        }
+      return r;
+    };
+    P_endo_names = get_field_names("endo_names");
+    P_exo_names = get_field_names("exo_names");
+    P_param_names = get_field_names("param_names");
+
+    endo_name_length = 0;
+    for (const auto &n : P_endo_names)
+      endo_name_length = max(endo_name_length, n.size());
+
     is_load_variable_list = false;
   }
 
@@ -276,21 +260,10 @@ public:
   inline void
   load_variable_list()
   {
-    ostringstream res;
-    for (unsigned int variable_num = 0; variable_num < static_cast<unsigned int>(nb_endo); variable_num++)
-      {
-        for (unsigned int i = 0; i < endo_name_length; i++)
-          if (P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)] != ' ')
-            res << P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)];
-        Variable_list.emplace_back(res.str(), SymbolType::endogenous, variable_num);
-      }
-    for (unsigned int variable_num = 0; variable_num < static_cast<unsigned int>(nb_exo); variable_num++)
-      {
-        for (unsigned int i = 0; i < exo_name_length; i++)
-          if (P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)] != ' ')
-            res << P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)];
-        Variable_list.emplace_back(res.str(), SymbolType::exogenous, variable_num);
-      }
+    for (unsigned int variable_num = 0; variable_num < P_endo_names.size(); variable_num++)
+      Variable_list.emplace_back(P_endo_names[variable_num], SymbolType::endogenous, variable_num);
+    for (unsigned int variable_num = 0; variable_num < P_exo_names.size(); variable_num++)
+      Variable_list.emplace_back(P_exo_names[variable_num], SymbolType::exogenous, variable_num);
   }
 
   inline int
@@ -320,44 +293,32 @@ public:
   inline string
   get_variable(SymbolType variable_type, unsigned int variable_num) const
   {
-    ostringstream res;
     switch (variable_type)
       {
       case SymbolType::endogenous:
-        if (variable_num <= nb_endo)
-          {
-            for (unsigned int i = 0; i < endo_name_length; i++)
-              if (P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)] != ' ')
-                res << P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)];
-          }
+        if (variable_num < P_endo_names.size())
+          return P_endo_names[variable_num];
         else
           mexPrintf("=> Unknown endogenous variable # %d", variable_num);
         break;
       case SymbolType::exogenous:
       case SymbolType::exogenousDet:
-        if (variable_num <= nb_exo)
-          {
-            for (unsigned int i = 0; i < exo_name_length; i++)
-              if (P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)] != ' ')
-                res << P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)];
-          }
+        if (variable_num < P_exo_names.size())
+          return P_exo_names[variable_num];
         else
           mexPrintf("=> Unknown exogenous variable # %d", variable_num);
         break;
       case SymbolType::parameter:
-        if (variable_num <= nb_param)
-          {
-            for (unsigned int i = 0; i < param_name_length; i++)
-              if (P_param_names[CHAR_LENGTH*(variable_num+i*nb_param)] != ' ')
-                res << P_param_names[CHAR_LENGTH*(variable_num+i*nb_param)];
-          }
+        if (variable_num < P_param_names.size())
+          return P_param_names[variable_num];
         else
           mexPrintf("=> Unknown parameter # %d", variable_num);
         break;
       default:
         break;
       }
-    return res.str();
+    cerr << "ErrorHandling::get_variable: Internal error";
+    exit(EXIT_FAILURE); // Silence GCC warning
   }
 
   inline string
diff --git a/mex/sources/bytecode/Interpreter.cc b/mex/sources/bytecode/Interpreter.cc
index be7d4be866d62ad8903ec4f825a882d4e1a87cb5..8fe3a141fea1bfa4c2cd160aab9d2524a623aea8 100644
--- a/mex/sources/bytecode/Interpreter.cc
+++ b/mex/sources/bytecode/Interpreter.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2007-2021 Dynare Team
+ * Copyright © 2007-2022 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -892,12 +892,9 @@ Interpreter::extended_path(const string &file_name, const string &bin_basename,
 
       if (old_print_it)
         {
-          ostringstream res, res1;
-          for (unsigned int i = 0; i < endo_name_length; i++)
-            if (P_endo_names[CHAR_LENGTH*(max_res_idx+i*y_size)] != ' ')
-              res << P_endo_names[CHAR_LENGTH*(max_res_idx+i*y_size)];
+          ostringstream res1;
           res1 << std::scientific << max_res;
-          mexPrintf("%s|%s| %4d  |  x  |\n", elastic(res.str(), endo_name_length_l+2, true).c_str(), elastic(res1.str(), real_max_length+2, false).c_str(), iter);
+          mexPrintf("%s|%s| %4d  |  x  |\n", elastic(P_endo_names[max_res_idx], endo_name_length_l+2, true).c_str(), elastic(res1.str(), real_max_length+2, false).c_str(), iter);
           mexPrintf(line.c_str());
           mexEvalString("drawnow;");
         }
diff --git a/mex/sources/bytecode/SparseMatrix.cc b/mex/sources/bytecode/SparseMatrix.cc
index b62b4fc90fb7426fac3ed2c485b173654824422b..dd90b4cd5f543c31b717651e9d3f5097b13fcd22 100644
--- a/mex/sources/bytecode/SparseMatrix.cc
+++ b/mex/sources/bytecode/SparseMatrix.cc
@@ -4094,7 +4094,7 @@ dynSparseMatrix::preconditioner_print_out(string s, int preconditioner, bool ss)
 }
 
 void
-dynSparseMatrix::Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin, int y_kmax,int Size, int periods, bool cvg, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, const char *P_endo_names, const vector_table_conditional_local_type &vector_table_conditional_local)
+dynSparseMatrix::Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin, int y_kmax,int Size, int periods, bool cvg, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, const vector<string> &P_endo_names, const vector_table_conditional_local_type &vector_table_conditional_local)
 {
   double top = 0.5;
   double bottom = 0.1;
@@ -4124,10 +4124,6 @@ dynSparseMatrix::Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin
           mexPrintf("res1 = %f, res2 = %f g0 = %f iter = %d\n", res1, res2, g0, iter);
           for (int j = 0; j < y_size; j++)
             {
-              ostringstream res;
-              for (unsigned int i = 0; i < endo_name_length; i++)
-                if (P_endo_names[CHAR_LENGTH*(j+i*y_size)] != ' ')
-                  res << P_endo_names[CHAR_LENGTH*(j+i*y_size)];
               bool select = false;
               for (int i = 0; i < Size; i++)
                 if (j == index_vara[i])
@@ -4136,9 +4132,9 @@ dynSparseMatrix::Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin
                     break;
                   }
               if (select)
-                mexPrintf("-> variable %s (%d) at time %d = %f direction = %f\n", res.str().c_str(), j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]);
+                mexPrintf("-> variable %s (%d) at time %d = %f direction = %f\n", P_endo_names[j].c_str(), j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]);
               else
-                mexPrintf("   variable %s (%d) at time %d = %f direction = %f\n", res.str().c_str(), j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]);
+                mexPrintf("   variable %s (%d) at time %d = %f direction = %f\n", P_endo_names[j].c_str(), j+1, it_, y[j+it_*y_size], direction[j+it_*y_size]);
             }
           if (iter == 0)
             throw FatalExceptionHandling(" in Simulate_Newton_Two_Boundaries, the initial values of endogenous variables are too far from the solution.\nChange them!\n");
diff --git a/mex/sources/bytecode/SparseMatrix.hh b/mex/sources/bytecode/SparseMatrix.hh
index dd3be23963d8fcd4603c3f3de1e85a3d93431f89..75c532f6daa41975816ca5922837c570233f2894 100644
--- a/mex/sources/bytecode/SparseMatrix.hh
+++ b/mex/sources/bytecode/SparseMatrix.hh
@@ -53,7 +53,7 @@ class dynSparseMatrix : public Evaluate
 public:
   dynSparseMatrix();
   dynSparseMatrix(int y_size_arg, int y_kmin_arg, int y_kmax_arg, bool print_it_arg, bool steady_state_arg, int periods_arg, int minimal_solving_periods_arg, double slowc_arg);
-  void Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin, int y_kmax, int Size, int periods, bool cvg, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, const char *P_endo_names, const vector_table_conditional_local_type &vector_table_conditional_local);
+  void Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin, int y_kmax, int Size, int periods, bool cvg, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, const vector<string> &P_endo_names, const vector_table_conditional_local_type &vector_table_conditional_local);
   void Simulate_Newton_One_Boundary(bool forward);
   void fixe_u(double **u, int u_count_int, int max_lag_plus_max_lead_plus_1);
   void Read_SparseMatrix(const string &file_name, int Size, int periods, int y_kmin, int y_kmax, bool two_boundaries, int stack_solve_algo, int solve_algo);