Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8638575
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T10:45:57+00:00 2026-06-12T10:45:57+00:00

This is a printing thread that prints the statistic of my currently running program

  • 0

This is a printing thread that prints the statistic of my currently running program

void StatThread::PrintStat(){
clock_t now = 0;
UINT64 oneMega = 1<<20;
const char* CUnique = 0;;
const char* CInserted = 0;;
while((BytesInserted<=fileSize.QuadPart)&&flag){
    Sleep(1000);
    now = clock();
    CUnique = FormatNumber(nUnique);
    CInserted = FormatNumber(nInserted);
    printf("[ %.2f%%] %u / %u dup %.2f%% @ %.2fM/s %.2fMB/s %3.2f%% %uMB\n",
        (double)BytesInserted*100/(fileSize.QuadPart),
        nUnique,nInserted,(nInserted-nUnique)*100/(double)nInserted,
        ((double)nInserted/1000000)/((now - start)/(double)CLOCKS_PER_SEC),
        ((double)BytesInserted/oneMega)/((now - start)/(double)CLOCKS_PER_SEC),
        cpu.GetCpuUtilization(NULL),cpu.GetProcessRAMUsage (true));
    if(BytesInserted==fileSize.QuadPart)
        flag=false;
}
delete[] CUnique;    //would have worked with memory leak if commented out
delete[] CInserted;  // crash at here! heap corruption 
}

This is FormatNumber that returns a pointer to a char array

const char* StatThread::FormatNumber(const UINT64& number) const{
char* result = new char[100];
result[0]='\0';
_i64toa_s(number,result,100,10);
DWORD nDigits = ceil(log10((double)number));
result[nDigits] = '\0';
if(nDigits>3){
    DWORD nComma=0;
    if(nDigits%3==0)
        nComma = (nDigits/3) -1;
    else
        nComma = nDigits/3;
    char* newResult = new char[nComma+nDigits+1];
    newResult[nComma+nDigits]='\0';
    for(DWORD i=1;i<=nComma+1;i++){
        memcpy(newResult+strlen(newResult)-i*3-(i-1),result+strlen(result)-i*3,3);
        if(i!=nComma+1){
            *(newResult+strlen(newResult)-4*i) = ',';   
        }
    }
    delete[] result; 
    return newResult;
}
return result;
}

What is really weird was that it crashed only in release mode because of a heap corruption, but run smoothly in debug mode. I’ve already checked everywhere and found no obvious memory leaks, and even Memory Leak Detector said so too.

Visual Leak Detector Version 2.2.3 installed.
The thread 0x958 has exited with code 0 (0x0).
No memory leaks detected.
Visual Leak Detector is now exiting.
The program '[5232] Caching.exe' has exited with code 0 (0x0).

However, when run in release mode,it threw an error that said my program stop working and I clicked on debug, it pointed to the line that caused the heap corruption.

The thread 0xe4c has exited with code 0 (0x0).
Unhandled exception at 0x00000000770E6AE2 (ntdll.dll) in Caching.exe:          0xC0000374: A heap has been corrupted (parameters: 0x000000007715D430).

If I commented out this line, it worked fine but Memory Leak Detector would have complained about memory leak! I don’t understand how to cause a heap corruption when there was no memory leaks, (at least that’s what the Leak Detector said). Please help, Thank you in advance.

Edit:
Heap corruption was fixed, because in the very last iteration, I still copied 3 byes to the front instead of whatever is leftover. Thank you all for helps!

const char* StatThread::FormatNumber(const UINT64& number) const{
char* result = new char[100];
result[0]='\0';
_ui64toa_s(number,result,100,10);
DWORD nDigits = (DWORD)ceil(log10((double)number));
if(number%10==0){
    nDigits++;
}
result[nDigits] = '\0';
if(nDigits>3){
    DWORD nComma=0;
    if(nDigits%3==0)
        nComma = (nDigits/3) -1;
    else
        nComma = nDigits/3;
    char* newResult = new char[nComma+nDigits+1];
    DWORD lenNewResult = nComma+nDigits;
    DWORD lenResult = nDigits;
    for(DWORD i=1;i<=nComma+1;i++){
        if(i!=nComma+1){
            memcpy(newResult+lenNewResult-4*i+1,result+lenResult-3*i,3);
            *(newResult+lenNewResult-4*i) = ',';    
        }
        else{
            memcpy(newResult,result,lenNewResult-4*(i-1));
        }
    }
    newResult[nComma+nDigits] = '\0';
    delete[] result; 
    return newResult;
}
return result;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T10:45:58+00:00Added an answer on June 12, 2026 at 10:45 am

    Sorry to be blunt, but the code to “format” a string is horrible.

    First of all, you pass in an unsigned 64-bit int value, which you formatted as a signed value instead. If you claim to sell bananas, you shouldn’t give your customers plantains instead.

    But what’s worse is that what you do return (when you don’t crash) isn’t even right. If a user passes in 0, well, then you return nothing at all. And if a user passes in 1000000 you return 100,000 and if he passes in 10000000 you return 1,000,000. Oh well, what’s a factor of 10 for some numbers between friends? 😉

    These, along with the crash, are symptoms of the crazy pointer arithmetic your code does. Now, to the bugs:

    First of all, when you allocate ‘newResult’ you leave the buffer in a very weird state. The first nComma + nDigits bytes are random values, followed by a NULL. You then call strlen on that buffer. The result of that strlen can be any number between 0 and nComma + nDigits, because any one of the nComma + nDigit characters may contain the null byte, which will cause strlen to terminate prematurely. In other words, the code is non-deterministic after that point.

    Sidenote: If you’re curious why it works in debug builds, it’s because the compiler and the debug version of the runtime libraries try to help you catch bugs by initializing memory for you. In Visual C++ the fill mask is usually 0xCC. This made sure that the bug in your strlen() was covered up in debug builds.

    Fixing that bug is pretty simple: simply initialize the buffer with spaces, followed by a NULL.

    char* newResult = new char[nComma+nDigits+1];
    memset(newResult, ' ', nComma+nDigits);
    newResult[nComma+nDigits]='\0';
    

    But there’s one more bug. Let’s try to format the number 1152921504606846975 which should become 1,152,921,504,606,846,975. Let’s see what some of fancy pointer arithmetic operations give us:

    memcpy(newResult + 25 - 3 - 0, result + 19 - 3, 3)
    *(newResult + 25 - 4) = ','
    memcpy(newResult + 25 - 6 - 1, result + 19 - 6, 3)
    *(newResult + 25 - 8) = ','
    memcpy(newResult + 25 - 9 - 2, result + 19 - 9, 3)
    *(newResult + 25 - 12) = ','
    memcpy(newResult + 25 - 12 - 3, result + 19 - 12, 3)
    *(newResult + 25 - 16) = ','
    memcpy(newResult + 25 - 15 - 4, result + 19 - 15, 3)
    *(newResult + 25 - 20) = ','
    memcpy(newResult + 25 - 18 - 5, result + 19 - 18, 3)
    *(newResult + 25 - 24) = ','
    memcpy(newResult + 25 - 21 - 6, result + 19 - 21, 3)
    

    As you can see, your very last operation copies data 2 bytes before the beginning of the buffer you allocated. This is because you assume that you will always be copying 3 characters. Of course, that’s not always the case.

    Frankly, I don’t think your version of FormatNumber should be fixed. all that pointer arithmetic and calculations are bugs waiting to happen. Here’s the version I wrote, which you can use if you want. I consider it much more sane, but your mileage may vary:

    const char *StatThread::FormatNumber(UINT64 number) const
    {
        // The longest 64-bit unsigned integer 0xFFFFFFFF is equal
        // to 18,446,744,073,709,551,615. That's 26 characters
        // so our buffer will be big enough to hold two of those
        // although, technically, we only need 6 extra characters
        // at most.
        const int buflen = 64;
    
        char *result = new char[buflen];
        int cnt = -1, idx = buflen;
    
        do
        {
            cnt++;
    
            if((cnt != 0) && ((cnt % 3) == 0))
                result[--idx] = ',';
    
            result[--idx] = '0' + (number % 10);
            number = number / 10;
        } while(number != 0);
    
        cnt = 0;
    
        while(idx != buflen)
            result[cnt++] = result[idx++];
    
        result[cnt] = 0;
    
        return result;
    }
    

    P.S.: The “off by a factor of 10” thing is left as an exerise to the reader.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Running this program is printing forked! 7 times. Can someone explain how forked! is
I have a class that extends Thread. This thread when running spends most of
In this below program i am printing the contents of the div when i
I have a thread function that looks something like this: DWORD WINAPI Thread_ProcessFile( LPVOID
I am developing a GUI to launch an external long-term running background program. This
I have a thread that loops receiving socket data and printing it: def post(self):
Why is this printing out 0 back in main but 6 when it is
I successfully inserted some data into my sqlite database(I confirmed this by printing out
Consider this Python code for printing a list of comma separated values for element
With this javascript I'm printing list of records: <script type=text/javascript> $(document).ready(function(){ function hide(){ $('#friend_list').fadeIn(100);

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.