Thread: Create struct on heap

  1. #1
    Registered User
    Join Date
    Nov 2016
    Posts
    84

    Create struct on heap

    Hi,

    I am trying to create struct instance on heap like this:

    Code:
    class Testhandler
    {
    
        struct TestParms {
    
        char parm1[48];
        char parm2[sizeof(void *)];
        char parm3[24];
        char parm4[8];
        char parm5[80];
    
            TestParms(){
            memset(TestParms, 0, sizeof(TestParms));
            };
    
        };
    }
    
    int main
    {
        const char * data = buffer.getBuffer();
        MQLONG data = buffer.tell();
    
        m_TestParms = new (std::nothrow) TestParms();
    
        memcpy(m_TestParms.parm1, eyeCatcher, sizeof(m_TestParms.parm1));
    
        memcpy(m_TestParms.parm2, &data, sizeof(m_TestParms.parm2));
    
        memcpy(m_TestParms.parm3, dataLength, sizeof(m_TestParms.parm3));
    
        memcpy(m_TestParms.parm4, msgDescriptor.Persistence, sizeof(m_TestParms.parm4));
    
        memcpy(m_TestParms.parm5, '  ', sizeof(m_TestParms.parm5));
    }
    msgDescriptor.Persistence has the MQ data type MQBYTE24 and eyeCatcher is const char.

    But this is not compiling. What is my mistake?
    Last edited by Joe1903; 11-05-2019 at 02:40 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    * moved to C++ programming forum *
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Joe1903
    But this is not compiling. What is my mistake?
    Your first mistake is not posting the smallest and simplest program that you expect should compile, but which results in a particular compile error. Your second mistake is not posting the compile error.

    Besides these, one obvious mistake is that you wrapped the TestParms struct in a class, but nowhere do you ever use that class.

    Yet another mistake is that you used m_TestParms without declaring it... but because of your first two mistakes, it is impossible to tell if this is a mistake or merely some abbreviated code. Related to this: because you chose to use nothrow new, you must check that the pointer is not a null pointer before using it. I suggest not using nothrow new unless you really must. Oh, and then you must delete what you new... but post-C++11, we would use a std::unique_ptr<TestParms> with std::make_unique instead of directly using new and delete.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    Registered User
    Join Date
    Nov 2016
    Posts
    84
    Quote Originally Posted by laserlight View Post

    Besides these, one obvious mistake is that you wrapped the TestParms struct in a class, but nowhere do you ever use that class.
    Code:
    Testhandler::m_TestParms = new (std::nothrow) TestParms();
    
    if (m_TestParms == 0)
    {
        throw ...
    }
    Is that better?

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    No. If I were you, I would start with something simpler, e.g.,
    Code:
    #include <memory>
    #include <string>
    #include <cstring>
    #include <iostream>
    
    struct TestParms
    {
        char parm1[48];
        char parm2[sizeof(void *)];
        char parm3[24];
        char parm4[8];
        char parm5[80];
    };
    
    int main()
    {
        auto testParms = std::make_unique<TestParms>();
        std::string input{"hello"};
        std::memcpy(testParms->parm1, &input[0], input.length());
        std::cout << testParms->parm1 << std::endl;
        std::cout << static_cast<int>(testParms->parm5[10]) << std::endl;
    }
    Now, std::make_unique performs value initialisation, which means that the member arrays will be zero initialised. If you prefer, you could still provide a constructor, but your use of memcpy in the constructor is wrong: it may be simpler to just use the initialiser list.

    Once you get this to work, you can then add in the memcpy calls for the various member arrays. Once you get that to work, you can then add the class wrapper: the thing that you're missing is a declaration of m_TestParms as a member of the class. (Also pay attention to private versus public member access.)
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Nov 2016
    Posts
    84
    Quote Originally Posted by laserlight View Post
    No. If I were you, I would start with something simpler, e.g.,
    Code:
    #include <memory>
    #include <string>
    #include <cstring>
    #include <iostream>
    
    struct TestParms
    {
        char parm1[48];
        char parm2[sizeof(void *)];
        char parm3[24];
        char parm4[8];
        char parm5[80];
    };
    
    int main()
    {
        auto testParms = std::make_unique<TestParms>();
        std::string input{"hello"};
        std::memcpy(testParms->parm1, &input[0], input.length());
        std::cout << testParms->parm1 << std::endl;
        std::cout << static_cast<int>(testParms->parm5[10]) << std::endl;
    }
    Now, std::make_unique performs value initialisation, which means that the member arrays will be zero initialised. If you prefer, you could still provide a constructor, but your use of memcpy in the constructor is wrong: it may be simpler to just use the initialiser list.

    Once you get this to work, you can then add in the memcpy calls for the various member arrays. Once you get that to work, you can then add the class wrapper: the thing that you're missing is a declaration of m_TestParms as a member of the class. (Also pay attention to private versus public member access.)
    Ok I will do.Meanwhile another question: what would be the difference if I do this (within the main):

    TestParms myStruct;

    Would that create an object myStruct which I can access the members with myStruct.parm1?

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Yes, but then you won't meet your "create struct instance on heap" requirement.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Nov 2016
    Posts
    84
    Quote Originally Posted by laserlight View Post
    Yes, but then you won't meet your "create struct instance on heap" requirement.
    Ok understand. What I want to do is following: I want to copy parameter values into my struct variables and give the pointer to the memory as parameter to call a Cobol module. What is better my first try or the second one? Or it makes no difference for this purpose?

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The second is probably better: you can just take the address of the local variable at the end. No need to worry about unique_ptr and even think about memory management.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Nov 2016
    Posts
    84
    Quote Originally Posted by laserlight View Post
    The second is probably better: you can just take the address of the local variable at the end. No need to worry about unique_ptr and even think about memory management.
    I thought something like this:

    TestParms * testParmsPtr = &myStruct;

    Last question: For my second try, would my constructor set all parms to 0 (memset)? Is this correct how I did it?
    And do you know anything about MQ data types? I am not sure whether this would work:

    memcpy(myStruct.parm4, dataLength, sizeof(myStruct.parm4)); as the data type of dataLength is MQLONG (32-bit integer) and parm4 is char[8].
    Last edited by Joe1903; 11-05-2019 at 06:04 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Read file, Create struct 5x5 numbers
    By Leite33 in forum C Programming
    Replies: 3
    Last Post: 12-12-2015, 11:29 AM
  2. Create struct tm from user specified date
    By cunzlow in forum C Programming
    Replies: 4
    Last Post: 09-30-2009, 12:39 PM
  3. How to create a matrix in the heap....
    By Tyrant in forum C Programming
    Replies: 10
    Last Post: 12-02-2007, 11:10 PM
  4. Use struct to create a boolean type
    By skyglin in forum C Programming
    Replies: 6
    Last Post: 06-18-2003, 08:21 PM
  5. about arrays create within a struct~
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 04-26-2002, 04:21 AM

Tags for this Thread