954,487 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Garbage From File

I am getting extra garbage at the end of the string returned by this function. Why?

char *read(char *fname)
{
    FILE *file=fopen(fname,"r");
    printf("Opening input file...\n");
    if (file==NULL)
        return NULL;
    int length=0;
    char *ret=new char[length];
    while (!feof(file))
    {
        char ch=fgetc(file);
        char *temp=new char[length+1];
        for (int i=0; i<length; i++)
            temp[i]=ret[i];
        delete[]ret;
        if (ch==EOF)
            ch=0;
        temp[length++]=ch;
        ret=temp;
    }
    fclose(file);
    return ret;
}
Labdabeta
Posting Pro in Training
489 posts since Feb 2011
Reputation Points: 27
Solved Threads: 18
 

Let me explain a little further. In my debugger this all works fine, but when I actually run the program outside the debugger it fails... but why?

Labdabeta
Posting Pro in Training
489 posts since Feb 2011
Reputation Points: 27
Solved Threads: 18
 

Sorry, my ideas were not gathered. Let me rephrase, I have a crash in this function but only when I run it outside the debugger. I get to the commented line before failure:

void write(char *text, char *fname)
{
    if (text==NULL)
        return;
    FILE *file=fopen(fname,"w");
    printf("Opening output file...\n");
    if (file==NULL)
        return;
    printf("Printing to file...\n");
    for (int i=0; text[i]; i++)
    {
        fputc(text[i],file);//failure here... but why?!
        printf("%c",text[i]);
    }
    printf("Done printing to file...\n");
    fclose(file);
}
Labdabeta
Posting Pro in Training
489 posts since Feb 2011
Reputation Points: 27
Solved Threads: 18
 

i must be going out of bounds for the array text.

In your first code, why are you using new to gettemp then you delete ret?

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

The code for read() works fine, its write() that is only working in the debugger and not outside of it. When I debug the program executes with no problem and with the expected output, but when I just run it outside the debugger it crashes and a windows error report screen pops up. Why does my write() function fail only outside the debugger?

Labdabeta
Posting Pro in Training
489 posts since Feb 2011
Reputation Points: 27
Solved Threads: 18
 

I attached a word document that better explains using pictures. This has me stumped, I cannot think of any reason why the debugger can run the code successfully but outside it the code fails.

Attachments This_is_run_inside_the_debugger.docx (244.59KB) main.cpp (14.03KB)
Labdabeta
Posting Pro in Training
489 posts since Feb 2011
Reputation Points: 27
Solved Threads: 18
 

It seems to me that this piece of code is suspicious, in the "highlight" function, towards the end, you have:

char *temp=new char[len(text)+108];
    sprintf(temp,"<table width=\"100%%\" border=\"0\" cellspacing=\"0\">\n<tr>\n<td>1.</td>\n<td bgcolor=\"#FFFFFF\">%s</span></td>\n</tr>\n</table>",text);

I counted 116 additional characters (considering the newlines to be one character, which is not the case on all OSes). You should be using strcat instead.

I highly, highly recommend that you use std::string instead of C-style strings. I mean, all the code you have would be a heck of a lot more robust, faster and simpler if you used std::string instead.

Usually when you have code that works fine in debug mode and crashes or misbehaves in normal or release mode, it usually means that you have a memory corruption problem. Usually, debug-runs have additional code that fills any uninitialized memory with dummy values (like 0 or some hex pattern like 0xBAADF00D ). So, if your code happens to work fine in debug mode it is usually due to accessing memory that is either uninitialized or unused or used by something else and happens to have been zeroed, when in release mode that is no longer the case and your program crashes. In other words, the main thing that changes between debug and release execution modes is the resulting memory pattern and "empty" values, which should not have any effect on your code as long as you are not accessing memory that you shouldn't access and that you are not using uninitialized memory. In your case, and by seeing your code, I suspect you are doing both, and using std::string instead could pretty much insure that your do neither.

mike_2000_17
Posting Virtuoso
Moderator
2,134 posts since Jul 2010
Reputation Points: 1,634
Solved Threads: 457
 

Ok, I changed those lines to:

char *temp=new char[len(text)+len("<table width=\"100%%\" border=\"0\" cellspacing=\"0\">\n<tr>\n<td>1.</td>\n<td bgcolor=\"#FFFFFF\">")+len("</span></td>\n</tr>\n</table>")];
    sprintf(temp,"<table width=\"100%%\" border=\"0\" cellspacing=\"0\">\n<tr>\n<td>1.</td>\n<td bgcolor=\"#FFFFFF\">%s</span></td>\n</tr>\n</table>",text);

just for a temporary fix. I am now working on converting it to std::string. I guess I just thought that using c-strings would be faster since I don't need all the functionality of an std::string. I guess I was wrong. Thanks!

Labdabeta
Posting Pro in Training
489 posts since Feb 2011
Reputation Points: 27
Solved Threads: 18
 

>>I guess I just thought that using c-strings would be faster since I don't need all the functionality of an std::string. I guess I was wrong. Thanks!

In C++, the default choice should always be std::string , it will always be easier than C-style strings and usually faster in execution time too (or the same, depending on your skill at writing the C-style version of the code). C-style strings only appear in special circumstances (like interfacing with a C library). Then there are more advanced applications where std::string isn't sufficient and where more feature-rich tools are required (anything from std::stringstream , to boost::tokenizer , to boost::spirit ). But, the default is always std::string , because if you don't need all its features, the compiler won't make you pay a performance penalty (or additional code) for the features you don't use, so don't be afraid to use it even in the simplest use-cases.

mike_2000_17
Posting Virtuoso
Moderator
2,134 posts since Jul 2010
Reputation Points: 1,634
Solved Threads: 457
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: