1. We have moved from vBulletin to XenForo and you are viewing the site in the middle of the move. Though the functional aspect of everything is working fine, we are still working on other changes including the new design on Xenforo.
    Dismiss Notice

Using auto_ptr or shared_ptr to allocate memory to a Structure

Discussion in 'C' started by ronan_40060, Nov 25, 2008.

  1. ronan_40060

    ronan_40060 New Member

    Dear Experts

    In our application the values that are sent from FRONT end( Java) are stored in a C++ Structure on Unix box and then a remote procedure call is made .
    To store the values that are coming from front end , Im allocating the memory using operator new as below
    sys_corresp_struct * p_str_Corresp = (sys_corresp_struct*)new char[sizeof(sys_corresp_struct)];
    memset(p_str_Corresp,'\0',sizeof(sys_corresp_struct));
    where in sys_corresp_struct is the Structure to hold all the incoming values..
    then a function CopyToDcesys_corresp_structcopies the data as below

    void CCaslifUtility::CopyToDceSYS_CORRESP_STRUCT(sys_corresp_struct* output,SysCorrespStruct &input)
    {

    strcpy(char *)output->record_type,(char *)input->recordType.c_str());
    strcpy((char *)output->country_code,(char *)input->countryCode.c_str());
    strcpy((char *)output->leg_veh,(char *)input->legVeh.c_str());
    strcpy((char *)output->boff_code,(char *)input->boffCode.c_str());
    strcpy((char *)output->ref_num,(char *)input->refNum.c_str());
    strcpy((char *)output->seq_num,(char *)input->seqNum.c_str());
    strcpy((char *)output->prod_type,(char *)input->prodType.c_str());
    strcpy((char *)output->opn_type,(char *)input->opnType.c_str());
    strcpy((char *)output->txn_ccy,(char *)input->txnCcy.c_str());
    }
    After the data has been copied and the RPC has been made , the memory is released as
    delete [] p_str_Corresp;
    p_str_Corresp = NULL;
    I have been thinking of using an auto_ptr or shared_ptr (from Boost Libraries) instead of using new operator for better memory management.
    Can some show me how to allocate a memory to a structure using auto_ptr or shared_ptr ?
    Many Thanks
     
  2. xpi0t0s

    xpi0t0s Mentor

  3. ronan_40060

    ronan_40060 New Member

    Im not sure how to use auto ptr to allcoate a memory for a structure .
     
  4. xpi0t0s

    xpi0t0s Mentor

    Oh I see. You don't. You initialise an auto_ptr from an existing pointer, either with
    T *foo=new T;
    auto_ptr<T> bar(T);

    or with:
    auto_ptr<T> bar(new T);
     
  5. ronan_40060

    ronan_40060 New Member

    This is what I have
    auto_ptr<SYS_CORRESP_STRUCT> p_str_Corresp = new (SYS_CORRESP_STRUCT);

    memset(p_str_Corresp.get(),'\0',sizeof(SYS_CORRESP_STRUCT));

    conObj.CopyToDceSYS_CORRESP_STRUCT(p_str_Corresp.get(),pStrCorresp)
    and then possible have a constructor to do the copying like

    SYS_CORRESP_STRUCT: SYS_CORRESP_STRUCT(SysCorrespStruct*)
    {

    // code of void CCaslifUtility::CopyToDceSYS_CORRESP_STRUCT() goes here - or just call it
    }
    also
    do u see a potential bug when strcpy() is used instead of std::string types ??
    :confused:

    Thanks
     
  6. xpi0t0s

    xpi0t0s Mentor

    You don't need to call a constructor explicitly; it gets called automatically when you "new" an object.
    T *foo=new T; will automatically call T::T().

    Bugs when you use strcpy instead of string? Depends on the code. sizeof(string) != strlen(string.c_str()) so watch out you don't assume that it is, although you don't show how you defined the "output" class/structure so I can only guess. How is output::record_type defined and why do you want to cast it to char*? If it isn't already char* then I can almost 100% guarantee you don't want to strcpy to it.
     
  7. ronan_40060

    ronan_40060 New Member

    record_type is a member of a structure SYS_CORRESP_STRUCT and is a char array.
    where as recordType which comes from Java Front END is defined as
    string recordType;

    So my question is instead of using strcpy what if I use std:string to copy the value from input to output ?
    if yes then how ?
     
  8. xpi0t0s

    xpi0t0s Mentor

    If it's already a char* (or char[]) why do you need to cast it to char*?

    > strcpy...
    > (char *)... <-- this bit
    > ...output->record_type,(char *)input->recordType.c_str());

    Remove the casts and let me know what errors you get.
     
  9. ronan_40060

    ronan_40060 New Member

    auto_ptr<SYS_CORRESP_STRUCT> p_str_Corresp = new (SYS_CORRESP_STRUCT);
    declaration throws an error that
    SYS_CORRESP_STRUCT*' could not be converted to 'const auto_ptr<SYS_CORRESP_STRUCT> &'.

    so I declared as
    auto_ptr<SYS_CORRESP_STRUCT>p_str_Corresp (new SYS_CORRESP_STRUCT); which gets compiled without any issues

    Since the copying all the parameter values from JAVA to the local Structure SYS_CORRESP_STRUCT , I have used a custom strcpyDCE () function that is
    void strcpyDCE(std::String, const WSSP_STD_NS::String &, int) ; where in
    std::String is the o/p string and const WSSP_STD_NS::String & is the i/p string and int is the size to be copied
    and im using for example as below
    strcpyDCE(output->record_type.get(),input->recordType, 4);








     
  10. ronan_40060

    ronan_40060 New Member

    Previously
    for normal char* i used to allocate memory like
    char *dce_sTabName = (char *)malloc(strlen(sTabName.c_str())+1);
    memset((void *)dce_sTabName,'\0',strlen(sTabName.c_str())+1);
    strcpyDCE(dce_sTabName,(char *)sTabName.c_str(),30);
    here above 30 is the max size that can be used to copy
    Now using std::String class
    using just using
    std::String dce_sTabName; // declaration
    dce_sTabName = sTabName.c_str();
    // Here c_str() will append '\0' at the end of dce_sTabName
    NO need to mention how many bytes to be copied
    Let me know your views on it
     
  11. xpi0t0s

    xpi0t0s Mentor

    char *dce_sTabName = (char *)malloc(strlen(sTabName.c_str())+1);
    memset((void *)dce_sTabName,'\0',strlen(sTabName.c_str())+1);
    strcpyDCE(dce_sTabName,(char *)sTabName.c_str(),30);

    Why do you do a memset before the strcpy? Is freshly allocated memory "dirty" and needs "cleaning" before it can be used? The strcpy overwrites all allocated memory.

    Why does strcpyDCE take a numeric parameter (30)? Does this do something significantly different from strncpy?

    dce_sTabName = sTabName.c_str();

    Why not just do dce_sTabName = sTabName; if dce_sTabName is a std::string? Strings are designed to work that way.
     
  12. ronan_40060

    ronan_40060 New Member

    memset is done to initialize it to '\0' . strcpyDCE takes 30 s that the maximum allocated bytes to be copied is 30 only ,
    Im declaring dce_sTabName as std::String dce_sTabName;
    but sTabName is an char array so i thought of doing dce_sTabName = sTabName.c_str();

    The other question is .. I have used auto_ptr declaration like
    auto_ptr<SYS_CORRESP_STRUCT>p_str_Corresp (new SYS_CORRESP_STRUCT); which gets compiled without any issues as
    auto_ptr<SYS_CORRESP_STRUCT> p_str_Corresp = new (SYS_CORRESP_STRUCT);
    declaration throws an error that "SYS_CORRESP_STRUCT*' could not be converted to 'const auto_ptr<SYS_CORRESP_STRUCT> &'.
     
  13. xpi0t0s

    xpi0t0s Mentor

    sTabName can't be a char array because (char*)::c_str() doesn't exist. On the other hand, std::string::c_str() *does* exist, so the fact that you refer to sTabName.c_str(); shows that sTabName isn't a char array, might be a std::string, and is definitely a class that defines c_str() even if it's not a std::string.

    auto..sp(new SYS..) works because there is a constructor defined that takes a pointer to SYS.. (can't be bothered with all that typing, so using ".." to abbreviate the names)

    On the other hand, there is no auto_ptr<SYS..>::eek:perator=(SYS..*), so you get the error.

    By the way, new T is fine; you don't need to do new (T). Actually the latter is the syntax for placement new, which you really don't want to start using yet. Get the simple stuff sorted before going onto that kind of stuff.

    > memset is done to initialize it to '\0'

    Yeah, I know what memset does. Let me try a parallel question:
    int x; // x contains junk
    x=0; // equivalent to your memset. We set it to zero.
    x=2; // we wanted to initialise it to 2, but we felt we needed to initialise it to zero first.

    In this code the x=0; is completely redundant; we can safely set x to 2 without having to set it to zero first. As is your memset call. Hence the question: why do you feel you need to do that?
     
  14. ronan_40060

    ronan_40060 New Member

    many problems are solved thank so much for shaing ur knowledge and cleaing my doubts .. Sorry for not being active on the post
     

Share This Page