Initializing a Struct's variable const char* const* with C++












0















I am trying to solve a coding question that requires the results be returned using a given struct. The struct is defined as:



struct Answer
{
const char* const* lastNames;
unsigned numberOfPeople;

}


Where the lastNames is a pointer to last names that are each terminated by a non-alpha char. I can not seem to find any way to convert the vector of strings that I am using to compile all the last names into a variable that I can assign to lastNames. I have tried making a single string with all the last names and assigning it with c_str() like so:
Ans->lastName = allNames.c_str(); but this gives me an error. Due to the limitations of the question I am unable to change the struct variable to anything else. How can I assign a string to a const char* const*










share|improve this question





























    0















    I am trying to solve a coding question that requires the results be returned using a given struct. The struct is defined as:



    struct Answer
    {
    const char* const* lastNames;
    unsigned numberOfPeople;

    }


    Where the lastNames is a pointer to last names that are each terminated by a non-alpha char. I can not seem to find any way to convert the vector of strings that I am using to compile all the last names into a variable that I can assign to lastNames. I have tried making a single string with all the last names and assigning it with c_str() like so:
    Ans->lastName = allNames.c_str(); but this gives me an error. Due to the limitations of the question I am unable to change the struct variable to anything else. How can I assign a string to a const char* const*










    share|improve this question



























      0












      0








      0








      I am trying to solve a coding question that requires the results be returned using a given struct. The struct is defined as:



      struct Answer
      {
      const char* const* lastNames;
      unsigned numberOfPeople;

      }


      Where the lastNames is a pointer to last names that are each terminated by a non-alpha char. I can not seem to find any way to convert the vector of strings that I am using to compile all the last names into a variable that I can assign to lastNames. I have tried making a single string with all the last names and assigning it with c_str() like so:
      Ans->lastName = allNames.c_str(); but this gives me an error. Due to the limitations of the question I am unable to change the struct variable to anything else. How can I assign a string to a const char* const*










      share|improve this question
















      I am trying to solve a coding question that requires the results be returned using a given struct. The struct is defined as:



      struct Answer
      {
      const char* const* lastNames;
      unsigned numberOfPeople;

      }


      Where the lastNames is a pointer to last names that are each terminated by a non-alpha char. I can not seem to find any way to convert the vector of strings that I am using to compile all the last names into a variable that I can assign to lastNames. I have tried making a single string with all the last names and assigning it with c_str() like so:
      Ans->lastName = allNames.c_str(); but this gives me an error. Due to the limitations of the question I am unable to change the struct variable to anything else. How can I assign a string to a const char* const*







      c++






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 26 '18 at 2:11









      Govind Parmar

      13k53763




      13k53763










      asked Nov 26 '18 at 2:07









      Justin ThurmanJustin Thurman

      116




      116
























          3 Answers
          3






          active

          oldest

          votes


















          0














          A const member variable can only be assigned in the constructor.

          if you can add to the struct, define a constructor, and use the : lastname(value) syntax; or use the struct Answer myVar{value,number}; initialization, right where you declare your instance.



          Another - ugly, dangerous, and frowned upon - alternative is a cast: (char**) lastname = value;, or in C++ syntax reinterpret_cast<char**>(lastname) = value.
          If someone is teaching you either of those approaches, change the teacher.






          share|improve this answer





















          • 1





            The member isn’t const, though. It is a [mutable] pointer to a const pointer to const objects of char . Even if the member were const it could be initialized with direct initialization. The real issue is the added indirection.

            – Dietmar Kühl
            Nov 26 '18 at 2:24











          • The code in the second paragraph is ill-formed (compiler should reject it). The result of those casts is a pointer prvalue, which is not valid as left operand of the assignment operator

            – M.M
            Nov 26 '18 at 2:53













          • what is "value" in your answer? Are you casting a vector of strings to char**? You should be explicit that this is how to bypass the compiler error and instead crash at runtime.

            – Kenny Ostrom
            Nov 26 '18 at 13:34





















          2














          The structure being used effectively uses a C-style approach to defining a variable sized array of pointers to char (with const sprinkled over it). You’ll need storage for both the array of char const* as well as the entities pointed to. Here is how you could build it from a std::vector<std::string>:



          std::vector<std::string> strings = somehow_compute_the_strings();
          std::vector<char const*> array;
          for (std::string const& s: strings) {
          array.push_back(s.c_str());
          }

          Answer answer = { array.data(), array.size() };


          Of course, you can’t return answer without the pointer inside pointing to stale data: you’d need to keep the two std::vectors alive. Potentially these two objects could be made members of an object the function is called on. To actually return an object of type Answer without a place to hold on to the std::vectors you could allocate the relevant entities and accept that the result will yield a memory leak unless the caller can clean the result up.






          share|improve this answer

































            1














            You can't just cast stuff. struct Answer is expecting a char**, so you are going to have to build it and keep it valid as long as the struct Answer is in use. At least they were kind enough to let us know they don't intend to modify it or mess with cleaning up the memory, since it takes "const char * const *".



            #include <iostream>
            #include <vector>
            #include <string>
            #include <assert.h>

            typedef std::vector<std::string> VectorOfStrings_type;

            struct Answer
            {
            const char* const* lastNames;
            unsigned numberOfPeople;
            };

            class AnswerWrapper
            {
            private:
            // construct and maintain memory so the pointers in the Answer struct will be valid
            char ** lastNames;
            unsigned int numberOfPeople;

            public:
            AnswerWrapper(const VectorOfStrings_type &input){
            numberOfPeople = input.size();

            // create the array of pointers
            lastNames = static_cast<char**>(
            malloc(numberOfPeople * sizeof(char*))
            );

            // create each string
            for (unsigned int i = 0; i < numberOfPeople; ++i){
            const std::string &name = input[i];

            // allocate space
            lastNames[i] = static_cast<char*>(
            malloc(name.size() + 1)
            );

            // copy string
            strncpy(lastNames[i], name.data(), name.size());

            // add null terminator
            lastNames[i][name.size()] = '';
            }
            }

            operator Answer (){
            return Answer{ lastNames, numberOfPeople };
            }

            ~AnswerWrapper(){
            // critcally important, left as an exercise
            assert(0);
            }
            };

            void SomeFunctionWhichUsesAnswer(Answer a){
            // presumably you have some legacy C code here
            // but here's a quick and easy demo
            for (unsigned int i = 0; i < a.numberOfPeople; ++i)
            std::cout << a.lastNames[i] << std::endl;
            }

            int main() {
            // Here is your vector of strings
            VectorOfStrings_type myData { "custom formatted data goes here", "and more here", "and again" };

            // You must construct a buffer for the "Answer" type, which must remain in scope
            AnswerWrapper temp{ myData };

            // AnswerWrapper is currently in scope, so inside this function, the pointers will be valid
            SomeFunctionWhichUsesAnswer(temp);
            }


            Also, I noticed that the strings in Answer are not referred to as null terminated. That is a separate issue you can take care of.






            share|improve this answer
























            • Dietmar Kuhl's data structures look good. You can just use that inside AnswerWrapper.

              – Kenny Ostrom
              Nov 26 '18 at 23:51











            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53473921%2finitializing-a-structs-variable-const-char-const-with-c%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            A const member variable can only be assigned in the constructor.

            if you can add to the struct, define a constructor, and use the : lastname(value) syntax; or use the struct Answer myVar{value,number}; initialization, right where you declare your instance.



            Another - ugly, dangerous, and frowned upon - alternative is a cast: (char**) lastname = value;, or in C++ syntax reinterpret_cast<char**>(lastname) = value.
            If someone is teaching you either of those approaches, change the teacher.






            share|improve this answer





















            • 1





              The member isn’t const, though. It is a [mutable] pointer to a const pointer to const objects of char . Even if the member were const it could be initialized with direct initialization. The real issue is the added indirection.

              – Dietmar Kühl
              Nov 26 '18 at 2:24











            • The code in the second paragraph is ill-formed (compiler should reject it). The result of those casts is a pointer prvalue, which is not valid as left operand of the assignment operator

              – M.M
              Nov 26 '18 at 2:53













            • what is "value" in your answer? Are you casting a vector of strings to char**? You should be explicit that this is how to bypass the compiler error and instead crash at runtime.

              – Kenny Ostrom
              Nov 26 '18 at 13:34


















            0














            A const member variable can only be assigned in the constructor.

            if you can add to the struct, define a constructor, and use the : lastname(value) syntax; or use the struct Answer myVar{value,number}; initialization, right where you declare your instance.



            Another - ugly, dangerous, and frowned upon - alternative is a cast: (char**) lastname = value;, or in C++ syntax reinterpret_cast<char**>(lastname) = value.
            If someone is teaching you either of those approaches, change the teacher.






            share|improve this answer





















            • 1





              The member isn’t const, though. It is a [mutable] pointer to a const pointer to const objects of char . Even if the member were const it could be initialized with direct initialization. The real issue is the added indirection.

              – Dietmar Kühl
              Nov 26 '18 at 2:24











            • The code in the second paragraph is ill-formed (compiler should reject it). The result of those casts is a pointer prvalue, which is not valid as left operand of the assignment operator

              – M.M
              Nov 26 '18 at 2:53













            • what is "value" in your answer? Are you casting a vector of strings to char**? You should be explicit that this is how to bypass the compiler error and instead crash at runtime.

              – Kenny Ostrom
              Nov 26 '18 at 13:34
















            0












            0








            0







            A const member variable can only be assigned in the constructor.

            if you can add to the struct, define a constructor, and use the : lastname(value) syntax; or use the struct Answer myVar{value,number}; initialization, right where you declare your instance.



            Another - ugly, dangerous, and frowned upon - alternative is a cast: (char**) lastname = value;, or in C++ syntax reinterpret_cast<char**>(lastname) = value.
            If someone is teaching you either of those approaches, change the teacher.






            share|improve this answer















            A const member variable can only be assigned in the constructor.

            if you can add to the struct, define a constructor, and use the : lastname(value) syntax; or use the struct Answer myVar{value,number}; initialization, right where you declare your instance.



            Another - ugly, dangerous, and frowned upon - alternative is a cast: (char**) lastname = value;, or in C++ syntax reinterpret_cast<char**>(lastname) = value.
            If someone is teaching you either of those approaches, change the teacher.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 26 '18 at 2:24

























            answered Nov 26 '18 at 2:16









            AganjuAganju

            5,2021721




            5,2021721








            • 1





              The member isn’t const, though. It is a [mutable] pointer to a const pointer to const objects of char . Even if the member were const it could be initialized with direct initialization. The real issue is the added indirection.

              – Dietmar Kühl
              Nov 26 '18 at 2:24











            • The code in the second paragraph is ill-formed (compiler should reject it). The result of those casts is a pointer prvalue, which is not valid as left operand of the assignment operator

              – M.M
              Nov 26 '18 at 2:53













            • what is "value" in your answer? Are you casting a vector of strings to char**? You should be explicit that this is how to bypass the compiler error and instead crash at runtime.

              – Kenny Ostrom
              Nov 26 '18 at 13:34
















            • 1





              The member isn’t const, though. It is a [mutable] pointer to a const pointer to const objects of char . Even if the member were const it could be initialized with direct initialization. The real issue is the added indirection.

              – Dietmar Kühl
              Nov 26 '18 at 2:24











            • The code in the second paragraph is ill-formed (compiler should reject it). The result of those casts is a pointer prvalue, which is not valid as left operand of the assignment operator

              – M.M
              Nov 26 '18 at 2:53













            • what is "value" in your answer? Are you casting a vector of strings to char**? You should be explicit that this is how to bypass the compiler error and instead crash at runtime.

              – Kenny Ostrom
              Nov 26 '18 at 13:34










            1




            1





            The member isn’t const, though. It is a [mutable] pointer to a const pointer to const objects of char . Even if the member were const it could be initialized with direct initialization. The real issue is the added indirection.

            – Dietmar Kühl
            Nov 26 '18 at 2:24





            The member isn’t const, though. It is a [mutable] pointer to a const pointer to const objects of char . Even if the member were const it could be initialized with direct initialization. The real issue is the added indirection.

            – Dietmar Kühl
            Nov 26 '18 at 2:24













            The code in the second paragraph is ill-formed (compiler should reject it). The result of those casts is a pointer prvalue, which is not valid as left operand of the assignment operator

            – M.M
            Nov 26 '18 at 2:53







            The code in the second paragraph is ill-formed (compiler should reject it). The result of those casts is a pointer prvalue, which is not valid as left operand of the assignment operator

            – M.M
            Nov 26 '18 at 2:53















            what is "value" in your answer? Are you casting a vector of strings to char**? You should be explicit that this is how to bypass the compiler error and instead crash at runtime.

            – Kenny Ostrom
            Nov 26 '18 at 13:34







            what is "value" in your answer? Are you casting a vector of strings to char**? You should be explicit that this is how to bypass the compiler error and instead crash at runtime.

            – Kenny Ostrom
            Nov 26 '18 at 13:34















            2














            The structure being used effectively uses a C-style approach to defining a variable sized array of pointers to char (with const sprinkled over it). You’ll need storage for both the array of char const* as well as the entities pointed to. Here is how you could build it from a std::vector<std::string>:



            std::vector<std::string> strings = somehow_compute_the_strings();
            std::vector<char const*> array;
            for (std::string const& s: strings) {
            array.push_back(s.c_str());
            }

            Answer answer = { array.data(), array.size() };


            Of course, you can’t return answer without the pointer inside pointing to stale data: you’d need to keep the two std::vectors alive. Potentially these two objects could be made members of an object the function is called on. To actually return an object of type Answer without a place to hold on to the std::vectors you could allocate the relevant entities and accept that the result will yield a memory leak unless the caller can clean the result up.






            share|improve this answer






























              2














              The structure being used effectively uses a C-style approach to defining a variable sized array of pointers to char (with const sprinkled over it). You’ll need storage for both the array of char const* as well as the entities pointed to. Here is how you could build it from a std::vector<std::string>:



              std::vector<std::string> strings = somehow_compute_the_strings();
              std::vector<char const*> array;
              for (std::string const& s: strings) {
              array.push_back(s.c_str());
              }

              Answer answer = { array.data(), array.size() };


              Of course, you can’t return answer without the pointer inside pointing to stale data: you’d need to keep the two std::vectors alive. Potentially these two objects could be made members of an object the function is called on. To actually return an object of type Answer without a place to hold on to the std::vectors you could allocate the relevant entities and accept that the result will yield a memory leak unless the caller can clean the result up.






              share|improve this answer




























                2












                2








                2







                The structure being used effectively uses a C-style approach to defining a variable sized array of pointers to char (with const sprinkled over it). You’ll need storage for both the array of char const* as well as the entities pointed to. Here is how you could build it from a std::vector<std::string>:



                std::vector<std::string> strings = somehow_compute_the_strings();
                std::vector<char const*> array;
                for (std::string const& s: strings) {
                array.push_back(s.c_str());
                }

                Answer answer = { array.data(), array.size() };


                Of course, you can’t return answer without the pointer inside pointing to stale data: you’d need to keep the two std::vectors alive. Potentially these two objects could be made members of an object the function is called on. To actually return an object of type Answer without a place to hold on to the std::vectors you could allocate the relevant entities and accept that the result will yield a memory leak unless the caller can clean the result up.






                share|improve this answer















                The structure being used effectively uses a C-style approach to defining a variable sized array of pointers to char (with const sprinkled over it). You’ll need storage for both the array of char const* as well as the entities pointed to. Here is how you could build it from a std::vector<std::string>:



                std::vector<std::string> strings = somehow_compute_the_strings();
                std::vector<char const*> array;
                for (std::string const& s: strings) {
                array.push_back(s.c_str());
                }

                Answer answer = { array.data(), array.size() };


                Of course, you can’t return answer without the pointer inside pointing to stale data: you’d need to keep the two std::vectors alive. Potentially these two objects could be made members of an object the function is called on. To actually return an object of type Answer without a place to hold on to the std::vectors you could allocate the relevant entities and accept that the result will yield a memory leak unless the caller can clean the result up.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 26 '18 at 2:26

























                answered Nov 26 '18 at 2:21









                Dietmar KühlDietmar Kühl

                127k9157321




                127k9157321























                    1














                    You can't just cast stuff. struct Answer is expecting a char**, so you are going to have to build it and keep it valid as long as the struct Answer is in use. At least they were kind enough to let us know they don't intend to modify it or mess with cleaning up the memory, since it takes "const char * const *".



                    #include <iostream>
                    #include <vector>
                    #include <string>
                    #include <assert.h>

                    typedef std::vector<std::string> VectorOfStrings_type;

                    struct Answer
                    {
                    const char* const* lastNames;
                    unsigned numberOfPeople;
                    };

                    class AnswerWrapper
                    {
                    private:
                    // construct and maintain memory so the pointers in the Answer struct will be valid
                    char ** lastNames;
                    unsigned int numberOfPeople;

                    public:
                    AnswerWrapper(const VectorOfStrings_type &input){
                    numberOfPeople = input.size();

                    // create the array of pointers
                    lastNames = static_cast<char**>(
                    malloc(numberOfPeople * sizeof(char*))
                    );

                    // create each string
                    for (unsigned int i = 0; i < numberOfPeople; ++i){
                    const std::string &name = input[i];

                    // allocate space
                    lastNames[i] = static_cast<char*>(
                    malloc(name.size() + 1)
                    );

                    // copy string
                    strncpy(lastNames[i], name.data(), name.size());

                    // add null terminator
                    lastNames[i][name.size()] = '';
                    }
                    }

                    operator Answer (){
                    return Answer{ lastNames, numberOfPeople };
                    }

                    ~AnswerWrapper(){
                    // critcally important, left as an exercise
                    assert(0);
                    }
                    };

                    void SomeFunctionWhichUsesAnswer(Answer a){
                    // presumably you have some legacy C code here
                    // but here's a quick and easy demo
                    for (unsigned int i = 0; i < a.numberOfPeople; ++i)
                    std::cout << a.lastNames[i] << std::endl;
                    }

                    int main() {
                    // Here is your vector of strings
                    VectorOfStrings_type myData { "custom formatted data goes here", "and more here", "and again" };

                    // You must construct a buffer for the "Answer" type, which must remain in scope
                    AnswerWrapper temp{ myData };

                    // AnswerWrapper is currently in scope, so inside this function, the pointers will be valid
                    SomeFunctionWhichUsesAnswer(temp);
                    }


                    Also, I noticed that the strings in Answer are not referred to as null terminated. That is a separate issue you can take care of.






                    share|improve this answer
























                    • Dietmar Kuhl's data structures look good. You can just use that inside AnswerWrapper.

                      – Kenny Ostrom
                      Nov 26 '18 at 23:51
















                    1














                    You can't just cast stuff. struct Answer is expecting a char**, so you are going to have to build it and keep it valid as long as the struct Answer is in use. At least they were kind enough to let us know they don't intend to modify it or mess with cleaning up the memory, since it takes "const char * const *".



                    #include <iostream>
                    #include <vector>
                    #include <string>
                    #include <assert.h>

                    typedef std::vector<std::string> VectorOfStrings_type;

                    struct Answer
                    {
                    const char* const* lastNames;
                    unsigned numberOfPeople;
                    };

                    class AnswerWrapper
                    {
                    private:
                    // construct and maintain memory so the pointers in the Answer struct will be valid
                    char ** lastNames;
                    unsigned int numberOfPeople;

                    public:
                    AnswerWrapper(const VectorOfStrings_type &input){
                    numberOfPeople = input.size();

                    // create the array of pointers
                    lastNames = static_cast<char**>(
                    malloc(numberOfPeople * sizeof(char*))
                    );

                    // create each string
                    for (unsigned int i = 0; i < numberOfPeople; ++i){
                    const std::string &name = input[i];

                    // allocate space
                    lastNames[i] = static_cast<char*>(
                    malloc(name.size() + 1)
                    );

                    // copy string
                    strncpy(lastNames[i], name.data(), name.size());

                    // add null terminator
                    lastNames[i][name.size()] = '';
                    }
                    }

                    operator Answer (){
                    return Answer{ lastNames, numberOfPeople };
                    }

                    ~AnswerWrapper(){
                    // critcally important, left as an exercise
                    assert(0);
                    }
                    };

                    void SomeFunctionWhichUsesAnswer(Answer a){
                    // presumably you have some legacy C code here
                    // but here's a quick and easy demo
                    for (unsigned int i = 0; i < a.numberOfPeople; ++i)
                    std::cout << a.lastNames[i] << std::endl;
                    }

                    int main() {
                    // Here is your vector of strings
                    VectorOfStrings_type myData { "custom formatted data goes here", "and more here", "and again" };

                    // You must construct a buffer for the "Answer" type, which must remain in scope
                    AnswerWrapper temp{ myData };

                    // AnswerWrapper is currently in scope, so inside this function, the pointers will be valid
                    SomeFunctionWhichUsesAnswer(temp);
                    }


                    Also, I noticed that the strings in Answer are not referred to as null terminated. That is a separate issue you can take care of.






                    share|improve this answer
























                    • Dietmar Kuhl's data structures look good. You can just use that inside AnswerWrapper.

                      – Kenny Ostrom
                      Nov 26 '18 at 23:51














                    1












                    1








                    1







                    You can't just cast stuff. struct Answer is expecting a char**, so you are going to have to build it and keep it valid as long as the struct Answer is in use. At least they were kind enough to let us know they don't intend to modify it or mess with cleaning up the memory, since it takes "const char * const *".



                    #include <iostream>
                    #include <vector>
                    #include <string>
                    #include <assert.h>

                    typedef std::vector<std::string> VectorOfStrings_type;

                    struct Answer
                    {
                    const char* const* lastNames;
                    unsigned numberOfPeople;
                    };

                    class AnswerWrapper
                    {
                    private:
                    // construct and maintain memory so the pointers in the Answer struct will be valid
                    char ** lastNames;
                    unsigned int numberOfPeople;

                    public:
                    AnswerWrapper(const VectorOfStrings_type &input){
                    numberOfPeople = input.size();

                    // create the array of pointers
                    lastNames = static_cast<char**>(
                    malloc(numberOfPeople * sizeof(char*))
                    );

                    // create each string
                    for (unsigned int i = 0; i < numberOfPeople; ++i){
                    const std::string &name = input[i];

                    // allocate space
                    lastNames[i] = static_cast<char*>(
                    malloc(name.size() + 1)
                    );

                    // copy string
                    strncpy(lastNames[i], name.data(), name.size());

                    // add null terminator
                    lastNames[i][name.size()] = '';
                    }
                    }

                    operator Answer (){
                    return Answer{ lastNames, numberOfPeople };
                    }

                    ~AnswerWrapper(){
                    // critcally important, left as an exercise
                    assert(0);
                    }
                    };

                    void SomeFunctionWhichUsesAnswer(Answer a){
                    // presumably you have some legacy C code here
                    // but here's a quick and easy demo
                    for (unsigned int i = 0; i < a.numberOfPeople; ++i)
                    std::cout << a.lastNames[i] << std::endl;
                    }

                    int main() {
                    // Here is your vector of strings
                    VectorOfStrings_type myData { "custom formatted data goes here", "and more here", "and again" };

                    // You must construct a buffer for the "Answer" type, which must remain in scope
                    AnswerWrapper temp{ myData };

                    // AnswerWrapper is currently in scope, so inside this function, the pointers will be valid
                    SomeFunctionWhichUsesAnswer(temp);
                    }


                    Also, I noticed that the strings in Answer are not referred to as null terminated. That is a separate issue you can take care of.






                    share|improve this answer













                    You can't just cast stuff. struct Answer is expecting a char**, so you are going to have to build it and keep it valid as long as the struct Answer is in use. At least they were kind enough to let us know they don't intend to modify it or mess with cleaning up the memory, since it takes "const char * const *".



                    #include <iostream>
                    #include <vector>
                    #include <string>
                    #include <assert.h>

                    typedef std::vector<std::string> VectorOfStrings_type;

                    struct Answer
                    {
                    const char* const* lastNames;
                    unsigned numberOfPeople;
                    };

                    class AnswerWrapper
                    {
                    private:
                    // construct and maintain memory so the pointers in the Answer struct will be valid
                    char ** lastNames;
                    unsigned int numberOfPeople;

                    public:
                    AnswerWrapper(const VectorOfStrings_type &input){
                    numberOfPeople = input.size();

                    // create the array of pointers
                    lastNames = static_cast<char**>(
                    malloc(numberOfPeople * sizeof(char*))
                    );

                    // create each string
                    for (unsigned int i = 0; i < numberOfPeople; ++i){
                    const std::string &name = input[i];

                    // allocate space
                    lastNames[i] = static_cast<char*>(
                    malloc(name.size() + 1)
                    );

                    // copy string
                    strncpy(lastNames[i], name.data(), name.size());

                    // add null terminator
                    lastNames[i][name.size()] = '';
                    }
                    }

                    operator Answer (){
                    return Answer{ lastNames, numberOfPeople };
                    }

                    ~AnswerWrapper(){
                    // critcally important, left as an exercise
                    assert(0);
                    }
                    };

                    void SomeFunctionWhichUsesAnswer(Answer a){
                    // presumably you have some legacy C code here
                    // but here's a quick and easy demo
                    for (unsigned int i = 0; i < a.numberOfPeople; ++i)
                    std::cout << a.lastNames[i] << std::endl;
                    }

                    int main() {
                    // Here is your vector of strings
                    VectorOfStrings_type myData { "custom formatted data goes here", "and more here", "and again" };

                    // You must construct a buffer for the "Answer" type, which must remain in scope
                    AnswerWrapper temp{ myData };

                    // AnswerWrapper is currently in scope, so inside this function, the pointers will be valid
                    SomeFunctionWhichUsesAnswer(temp);
                    }


                    Also, I noticed that the strings in Answer are not referred to as null terminated. That is a separate issue you can take care of.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 26 '18 at 13:32









                    Kenny OstromKenny Ostrom

                    2,9651220




                    2,9651220













                    • Dietmar Kuhl's data structures look good. You can just use that inside AnswerWrapper.

                      – Kenny Ostrom
                      Nov 26 '18 at 23:51



















                    • Dietmar Kuhl's data structures look good. You can just use that inside AnswerWrapper.

                      – Kenny Ostrom
                      Nov 26 '18 at 23:51

















                    Dietmar Kuhl's data structures look good. You can just use that inside AnswerWrapper.

                    – Kenny Ostrom
                    Nov 26 '18 at 23:51





                    Dietmar Kuhl's data structures look good. You can just use that inside AnswerWrapper.

                    – Kenny Ostrom
                    Nov 26 '18 at 23:51


















                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53473921%2finitializing-a-structs-variable-const-char-const-with-c%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Costa Masnaga

                    Fotorealismo

                    Create new schema in PostgreSQL using DBeaver