Clarification related to memory mgmt of char * inside a function ...

Discussion in 'C Programming' started by Karthik D, Jul 1, 2003.

  1. Karthik D

    Karthik D Guest

    Hello All,
    Basically I would like to take suggestions from programmers
    about implementation of a function which processes some error
    messages.(fyi:this is not a homework problem)
    Let me explain my problem in detail.I have a function
    which closely emulates dlerror() function.
    The function is as below:

    void dlerror(void *handle, char *err, size_t len)
    {
    char *msg;
    /*
    * I am using some API(Win32)which converts the error number
    * to message and stores it in 'msg'.The memory for msg is
    * allocated by the API.So it needs to be freed before exiting
    * this function.
    */
    /*
    * So I try to copy msg into err using memcpy since I need
    * to have the error message in calling function
    */
    if (msg != NULL)
    {
    memcpy(err,msg,len);
    }
    /* freeing the memory allocated for msg */
    return;
    }


    The function is called as follows :

    int main()
    {
    void *hdl;
    char err[256];
    /*
    * ....
    */
    dlerror(hdl, err, sizeof(err));
    if (err != NULL)
    {
    printf("Error message is %s\n", err);
    }
    else
    printf("Error message is NULL\n");
    return 0;
    }

    Is this a correct way?If I am wrong or if there are any better/good ways
    could someone kindly suggest me how can I go about.

    I am finding difficulty in understanding
    - the memory manangement of char pointers/double char pointers
    inside a function and returning their values to another function
    etc..

    I have read C books.But if someone could provide some real-world
    insights on this,it would be helpful for me.

    Thanks & Regards,
    Karthik
     
    Karthik D, Jul 1, 2003
    #1
    1. Advertisements

  2. Karthik D

    signuts Guest

    On Tue, 01 Jul 2003 05:50:00 -0700, Karthik D wrote:

    > Hello All,
    > Basically I would like to take suggestions from programmers
    > about implementation of a function which processes some error
    > messages.(fyi:this is not a homework problem)
    > Let me explain my problem in detail.I have a function
    > which closely emulates dlerror() function.


    I'm not quite sure I understand what you're trying to do here. Maybe we
    could get more information on the arguments and what they mean for
    dlerror(..). As far as error detection and error number <=> error messages
    goes, I personally like checking the return values of the function and
    storing the error messages in a char array.

    const char *err_table[] = { "error1", "error2", "error3" };
    and with the help of an enum you can make the code look nice as well.

    > The function is as below:
    >
    > void dlerror(void *handle, char *err, size_t len)
    > {
    > char *msg;
    > /*
    > * I am using some API(Win32)which converts the error number
    > * to message and stores it in 'msg'.The memory for msg is
    > * allocated by the API.So it needs to be freed before exiting
    > * this function.
    > */
    > /*
    > * So I try to copy msg into err using memcpy since I need
    > * to have the error message in calling function
    > */
    > if (msg != NULL)
    > {
    > memcpy(err,msg,len);

    /* I would use strcpy here */
    > }
    > /* freeing the memory allocated for msg */

    /* i'm not sure how this is freeing the memory. */
    > return;
    > }
    >
    >
    > The function is called as follows :
    >
    > int main()
    > {
    > void *hdl;
    > char err[256];
    > /*
    > * ....
    > */
    > dlerror(hdl, err, sizeof(err));
    > if (err != NULL)
    > {
    > printf("Error message is %s\n", err);
    > }
    > else
    > printf("Error message is NULL\n");
    > return 0;
    > }
    >
    > Is this a correct way?If I am wrong or if there are any better/good ways
    > could someone kindly suggest me how can I go about.
    >
    > I am finding difficulty in understanding
    > - the memory manangement of char pointers/double char pointers
    > inside a function and returning their values to another function
    > etc..
    >
    > I have read C books.But if someone could provide some real-world
    > insights on this,it would be helpful for me.
    >
    > Thanks & Regards,
    > Karthik


    --
    Sig
    Tue Jul 1 11:11:11 EDT 2003
     
    signuts, Jul 1, 2003
    #2
    1. Advertisements

  3. Karthik D

    Dan Pop Guest

    In <> (Karthik D) writes:

    >void dlerror(void *handle, char *err, size_t len)
    >{
    > char *msg;
    > /*
    > * I am using some API(Win32)which converts the error number
    > * to message and stores it in 'msg'.The memory for msg is
    > * allocated by the API.So it needs to be freed before exiting
    > * this function. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    ^^^^^^^^^^^^^
    There is no such need, if the function passes the value of msg back to its
    caller.

    > */
    > /*
    > * So I try to copy msg into err using memcpy since I need
    > * to have the error message in calling function
    > */
    > if (msg != NULL)
    > {
    > memcpy(err,msg,len);
    > }


    This does NOT ensure that err contains a proper null-terminated string.
    Use something like this instead:

    *err = 0;
    strncat(err, msg, len - 1);

    and make sure that len has a positive value.

    > /* freeing the memory allocated for msg */
    > return;
    > }
    >
    >
    > The function is called as follows :
    >
    > int main()
    > {
    > void *hdl;
    > char err[256];
    > /*
    > * ....
    > */
    > dlerror(hdl, err, sizeof(err));
    > if (err != NULL)


    This test is downright idiotic! err is an array and the address of its
    first character is guaranteed not to be a null pointer.

    If dlerror() can't figure out an error message, there are two
    possibilities:

    1. Put a string like "failure of unknown origin" in err.

    2. Return a success/failure indication to its caller, instead of being
    a void function.

    > {
    > printf("Error message is %s\n", err);
    > }
    > else
    > printf("Error message is NULL\n");
    > return 0;
    > }
    >
    > Is this a correct way?


    Yes, with the objections mentioned above.

    > If I am wrong or if there are any better/good ways
    > could someone kindly suggest me how can I go about.


    Simply pass back the pointer obtained from the API to the caller and
    document that it is its responsibility to free it, after using it. It's
    more efficient and you don't have to bother with the size of the string
    containing the message. Your sample program becomes:

    char *dlerror(void *handle)
    {
    char *msg;
    /*
    * I am using some API(Win32)which converts the error number
    * to message and stores it in 'msg'.The memory for msg is
    * allocated by the API.
    */
    return msg;
    }

    int main()
    {
    void *hdl;
    char *err;
    /*
    * ....
    */
    err = dlerror(hdl);
    if (err != NULL) {
    printf("Error message is %s\n", err);
    /* freeing the memory allocated for msg */
    }
    else printf("Failure of unknown origin\n");
    return 0;
    }

    Note that everything is simpler and there is no pointless data copying.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Jul 1, 2003
    #3
  4. Karthik D

    Karthik D Guest

    Hello Dan/Signuts,
    Thanks for your answers/suggestions.Basically what I wanted to achieve
    is porting of dlerror to Windows(may be offtopic to clc).Sorry for bringing
    a offtopic to clc.
    Below is the code which achieves that.It has been suggested in
    MSDN to free the lpMsgBuf allocated by FormatMessage.That's the reason
    I copy it to another string and return it as mentioned in my previous
    posting.

    char *dlerror(void *handle)
    {
    LPVOID lpMsgBuf;
    DWORD lastError,fmtMsgError;
    char *errmsg=NULL;
    int len;

    if ( handle == NULL)
    {
    lastError = GetLastError(); //Get the Error value
    if (!FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    lastError,
    /* Default language */
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    (LPTSTR) &lpMsgBuf,
    0,
    NULL ))
    {
    /* Handle the error. */
    fmtMsgError = GetLastError();
    errmsg=malloc(256);
    sprintf(errmsg, "Format Message failed with errno:%ld",
    fmtMsgError);
    return errmsg;
    }
    len = strlen(lpMsgBuf);
    errmsg=malloc(len+1);
    strncpy(errmsg,lpMsgBuf,len);
    /* Free the buffer */
    LocalFree(lpMsgBuf);
    return errmsg;
    }
    else
    return errmsg;
    }

    If FormatMessage() fails then I am printing a hardcoded error message.
    The function dlerror is called as follows:
    /*
    * ..... some code ........
    */
    so_error = dlerror(so_handle);
    if (so_error != NULL)
    {
    fprintf(stdout,"%s\n", so_error);
    free(so_error);
    so_error = NULL;
    return r_ERR;
    }

    The variable is so_error is declared as:
    char *so_error;

    Is this correct?

    Thanks & Regards,
    Karthik
     
    Karthik D, Jul 2, 2003
    #4
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Krishnan

    ASP .Net pages - instance mgmt

    Krishnan, Apr 5, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    343
    Krishnan
    Apr 5, 2004
  2. =?Utf-8?B?QVZM?=

    state mgmt issue

    =?Utf-8?B?QVZM?=, Feb 13, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    364
    Steve C. Orr [MVP, MCSD]
    Feb 13, 2006
  3. Karthik D
    Replies:
    2
    Views:
    341
    Mike Wahler
    Oct 15, 2003
  4. richard

    memory mgmt problem

    richard, Sep 1, 2003, in forum: C Programming
    Replies:
    12
    Views:
    640
    richard
    Sep 2, 2003
  5. Mark Shelor

    Memory Mgmt Using C and Perl

    Mark Shelor, Jan 21, 2004, in forum: Perl Misc
    Replies:
    7
    Views:
    214
    Sisyphus
    Jan 22, 2004
Loading...

Share This Page