char * call-by-reference problem

S

Simon K

When I call
---->>> SetLog("WinMain", Msg("Loading %s ...", filename)); <<---


TCHAR *Msg(TCHAR *szFormat, ...)
{
TCHAR szBuffer[1024]=""; // Large buffer for long filenames or
URLs
const size_t NUMCHARS = sizeof(szBuffer) / sizeof(szBuffer[0]);
const int LASTCHAR = NUMCHARS - 1;

// Format the input string
va_list pArgs;
va_start(pArgs, szFormat);

// Use a bounded buffer size to prevent buffer overruns. Limit
count to
// character size minus one to allow for a NULL terminating
character.
_vsntprintf(szBuffer, NUMCHARS - 1, szFormat, pArgs);
va_end(pArgs);

// Ensure that the formatted string is NULL-terminated
szBuffer[LASTCHAR] = TEXT('\0');

// Display a message box with the formatted string
return szBuffer;
}

void SetLog(TCHAR *ID, TCHAR *szMsg)
{<-----------------------------------------------------szMsg =
szBuffer (of Msg(..))
TCHAR str[BUFSIZE]=""; <------------------------- szMsg reseted!
WHY!?!!!??
TCHAR gt1[BUFSIZE]="", gt2[BUFSIZE]="";
struct tm *newtime;
time_t aclock;
time( &aclock ); // Get time in seconds
newtime = localtime( &aclock ); // Convert time to struct tm form

_tcscpy(gt1, _tasctime(newtime));
_tcsncat(gt2, gt1, _tcslen(gt1)-1);

wsprintf(str, "[%s]%s : %s \n", gt2, ID, szMsg);

AppendText(ghSttEM, str);

FILE *stream = fopen("dc.log","a+");
_ftprintf(stream, str);
fclose(stream);
}




I go through SetLog, it first calls Msg(...) in order to display in
format.

As i debug step by step, I found out some weird problems...
I indicated the problem on the source, can someone tell me what's
going wrong with this code?
 
S

Simon K

When I call
 ---->>> SetLog("WinMain", Msg("Loading %s ...", filename)); <<---

TCHAR *Msg(TCHAR *szFormat, ...)
{
    TCHAR szBuffer[1024]="";  // Large buffer for long filenames or
URLs
    const size_t NUMCHARS = sizeof(szBuffer) / sizeof(szBuffer[0]);
    const int LASTCHAR = NUMCHARS - 1;

    // Format the input string
    va_list pArgs;
    va_start(pArgs, szFormat);

    // Use a bounded buffer size to prevent buffer overruns.  Limit
count to
    // character size minus one to allow for a NULL terminating
character.
    _vsntprintf(szBuffer, NUMCHARS - 1, szFormat, pArgs);
    va_end(pArgs);

    // Ensure that the formatted string is NULL-terminated
    szBuffer[LASTCHAR] = TEXT('\0');

    // Display a message box with the formatted string
    return szBuffer;

}

void SetLog(TCHAR *ID, TCHAR *szMsg)
{<-----------------------------------------------------szMsg =
szBuffer (of Msg(..))
        TCHAR str[BUFSIZE]="";  <------------------------- szMsg reseted!
WHY!?!!!??
        TCHAR gt1[BUFSIZE]="", gt2[BUFSIZE]="";
        struct tm *newtime;
        time_t aclock;
        time( &aclock );   // Get time in seconds
        newtime = localtime( &aclock );   // Convert time to struct tm form

        _tcscpy(gt1, _tasctime(newtime));
        _tcsncat(gt2, gt1, _tcslen(gt1)-1);

        wsprintf(str, "[%s]%s : %s \n", gt2, ID, szMsg); ------>> szMsg = str!!! WHY!?!?!?

        AppendText(ghSttEM, str);

        FILE *stream = fopen("dc.log","a+");
        _ftprintf(stream,  str);
        fclose(stream);

}

I go through SetLog, it first calls Msg(...) in order to display in
format.

As i debug step by step, I found out some weird problems...
I indicated the problem on the source, can someone tell me what's
going wrong with this code?

One thing more, I indicated one more problem up here.
 
O

Obnoxious User

When I call
---->>> SetLog("WinMain", Msg("Loading %s ...", filename)); <<---


TCHAR *Msg(TCHAR *szFormat, ...)
{
TCHAR szBuffer[1024]=""; // Large buffer for long filenames or
URLs

Local object.


[snip>
// Display a message box with the formatted string return szBuffer;

I assume there is an actual return statement here, or?
It returns a local object which dies when the function exits.
}

void SetLog(TCHAR *ID, TCHAR *szMsg)
{<-----------------------------------------------------szMsg = szBuffer
(of Msg(..))
TCHAR str[BUFSIZE]=""; <------------------------- szMsg reseted!
WHY!?!!!??

Why? Since SetLog() is called directly after Msg() it most likely
overwrites the stack part that Msg() used with its own local object.

[snip]
I go through SetLog, it first calls Msg(...) in order to display in
format.

As i debug step by step, I found out some weird problems... I indicated
the problem on the source, can someone tell me what's going wrong with
this code?

It's written terribly wrong. Compare to this example:

#include <iostream>

int * get_address_to_local_object() {
int local[1024] = {1};
return &local[0];
}

void use_invalid_pointer(int * ptr) {
int local[1024] = {0};
std::cout<<ptr[0]<<std::endl;
}


int main() {
use_invalid_pointer(get_address_to_local_object());
return 0;
}

If you're lucky it will print 0 to illustrate the problem:

:~$ g++ test.cpp
test.cpp: In function ‘int* get_address_to_local_object()’:
test.cpp:4: warning: address of local variable ‘local’ returned
:~$ ./a.out
0
:~$
 
S

Simon K

When I call
---->>> SetLog("WinMain", Msg("Loading %s ...", filename)); <<---
TCHAR *Msg(TCHAR *szFormat, ...)
{
TCHAR szBuffer[1024]=""; // Large buffer for long filenames or
URLs

Local object.

[snip>


// Display a message box with the formatted string return szBuffer;

I assume there is an actual return statement here, or?
It returns a local object which dies when the function exits.
void SetLog(TCHAR *ID, TCHAR *szMsg)
{<-----------------------------------------------------szMsg = szBuffer
(of Msg(..))
TCHAR str[BUFSIZE]=""; <------------------------- szMsg reseted!
WHY!?!!!??

Why? Since SetLog() is called directly after Msg() it most likely
overwrites the stack part that Msg() used with its own local object.

[snip]


I go through SetLog, it first calls Msg(...) in order to display in
format.
As i debug step by step, I found out some weird problems... I indicated
the problem on the source, can someone tell me what's going wrong with
this code?

It's written terribly wrong. Compare to this example:

#include <iostream>

int * get_address_to_local_object() {
int local[1024] = {1};
return &local[0];

}

void use_invalid_pointer(int * ptr) {
int local[1024] = {0};
std::cout<<ptr[0]<<std::endl;

}

int main() {
use_invalid_pointer(get_address_to_local_object());
return 0;

}

If you're lucky it will print 0 to illustrate the problem:

:~$ g++ test.cpp
test.cpp: In function 'int* get_address_to_local_object()':
test.cpp:4: warning: address of local variable 'local' returned
:~$ ./a.out
0
:~$

I just looked up to find out what was wrong, exactly what u said.
Thou, I can't figure out how to solve this problem.
 
S

Simon K

It looks really stupid to answer my own question but I just found out
one solution :)

In Msg,

TCHAR *Msg(TCHAR *szFormat, ...)
{
TCHAR szBuffer[1024]=""; // Large buffer for long filenames or
URLs


I changed

TCHAR szBuffer[1024]=""; ==> static TCHAR szBuffer[1024]="";

and added one more line,
ZeroMemory(szBuffer, sizeof(szBuffer));

in order to reset szBuffer everytime I get thru Msg.


Well, I don't think this is a firm solution, any better idea?
 
O

Obnoxious User

[Please quote some context.]

It looks really stupid to answer my own question but I just found out
one solution :)

In Msg,

TCHAR *Msg(TCHAR *szFormat, ...)
{
TCHAR szBuffer[1024]=""; // Large buffer for long filenames or
URLs


I changed

TCHAR szBuffer[1024]=""; ==> static TCHAR szBuffer[1024]="";

and added one more line,
ZeroMemory(szBuffer, sizeof(szBuffer));
Unnecessary.


in order to reset szBuffer everytime I get thru Msg.

int written = _vsntprintf(szBuffer, NUMCHARS - 1, szFormat, pArgs);
if(written == -1) throw "error";
szBuffer[written] = 0;
Well, I don't think this is a firm solution, any better idea?

boost::shared_ptr<>, std::string, std::vector, so many options

And what about this situation:

TCHAR * m1 = Msg("Loading %s ...", filename);
TCHAR * m2 = Msg("Loading %s ...", filename);

SetLog("WinMain", m1);
SetLog("WinMain", m2);
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top