1

I want to write a function that simply returns a string so I can do this:

TCHAR sVar[256] = {0};
_stprintf(sVar,L"%s",GetCurrentTime());

I can't implement this functionality with the following function b/c memory is freed before returning the value:

TCHAR *GetCurrentTime(void)
{
    TCHAR *sVal;
    sVal = (TCHAR *) calloc(64+1, sizeof(TCHAR));       
    GetCurrentTimeEx(sVal); // Populates
    free(sVal);sVal=NULL;
    return sVal;
}

and I can't do this function because there's a memory leak if I don't remember to free the memory in the calling program, which defeats the purpose of having a simple function return a char string:

TCHAR *GetCurrentTime(void)
{
    TCHAR *sVal;
    sVal = (TCHAR *) calloc(64+1, sizeof(TCHAR));
    GetCurrentTimeEx(sVal);
    return sVal;
}

and I don't want to declare memory off of the stack.:

TCHAR *GetCurrentTime(void)
{
    static TCHAR sVal[64];
    GetCurrentTimeEx(sVal);
    return sVal;
}

(here is the function that gets the time):

DWORD GetTime(TCHAR *sCurrentTime)
{
    TCHAR sTime[9] = {0};
    if (_tstrtime_s(sTime, 9) == ERROR_SUCCESS)
        {
        INT i;
        for (i=0;i<=4;i++)
            sCurrentTime[i] = sTime[i];
        return 1;
        }
    else
        return 0;
}

I searched but could not find an answer to this pretty common question. Can someone help me? Thanks.

4
  • 1
    What you ask for does not exist. The closest is larsmans' solution, though it has severe disadvantages. If you can live with those. However, the better approach overall would be QuantumMechanic's solution. Commented Apr 26, 2011 at 11:25
  • Note that TCHAR, _stprintf, GetCurrentTime, GetCurrentTimeEx, DWORD, and _tstrtime_s are not defined in either Standard C or POSIX. If they are not defined by you in your own (not showed) code, you're unnecessarily locking yourself to the implementation you use. Also don't cast the return value of calloc: it is not needed and may hide errors. Commented Apr 26, 2011 at 11:26
  • Why not pass any arguments? A simple void writeToMyBuffer(char *buf, int buflen) could do the job. You allocate memory outside the function and just give a pointer to that region. Another way would be to use a global variable. Commented Apr 26, 2011 at 11:30
  • What about if I did pass an argument, like GetCurrentTimeEx(sTmp), and it also returned a TCHAR? Since I can't have the ideal, how can I implement this like the Win32 function PathAddBackslash? Commented Apr 26, 2011 at 11:51

3 Answers 3

4

You can do this with a static buffer, as in your own example:

char *GetCurrentTime(void)
{
    static char sVal[64];
    GetCurrentTimeEx(sVal);
    return sVal;
}

which actually does not allocate memory on the stack, but in the static region. This solution is not re-entrant and not thread-safe, but it's the only way to get the exact idiom you want in C without memory leaks.

The idiomatic solution would be to make memory allocation the responsibility of the caller and pass a buffer as an argument.

Sign up to request clarification or add additional context in comments.

1 Comment

@JeffR: because static means that there is only one sval buffer per process, so if GetCurrentTime is called nearly simultaneously by two threads, they may simultaneously write to this single buffer, or one may overwrite the result of the other before it returns its value, etc.
2

You could pass in a pre-allocated TCHAR* that GetCurrentTime() would use to put the time in:

TCHAR *GetCurrentTime(TCHAR *buf)
{
    GetCurrentTimeEx(buf);
    return buf;
}

And that call it like this:

TCHAR buf[64+1];
_stprintf(sVar,L"%s",GetCurrentTime(buf));

Or as

TCHAR buf[64+1];
GetCurrentTime(buf);
_stprintf(sVar,L"%s",buf);

Though of course that is allocated off the stack, which you might not want. On the other hand, since it is not static it will at least be re-entrant in a multi-threaded environment.

Comments

0

There are three ways to create an object in C - dynamically (with malloc et al), automatically (on the stack) and statically. You say you don't want to do any of these, in which case I'm afraid you are out of luck.

1 Comment

What about if I did pass an argument, like GetCurrentTimeEx(sTmp), and it also returned a TCHAR? Since I can't have the ideal, how can I implement this like the Win32 function PathAddBackslash?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.