tags:

views:

168

answers:

4

hi,

i'm having a weird problem with allocating memory in c++ i'm creating a buffer and read file content into it. problem is the allocating is incorrect and at the end of the printing there are weird chars... the content of the file is "Hello"... i'm sitting on it for hours... what can be the problem ? :(

void main()
{
 FILE *fp;
 char *buffer;
 long file_size;
 size_t result;

 fp = fopen("input.txt","r");
 if (fp == NULL) { fputs("File Error",stderr); exit(1); }

 //get file size
 fseek(fp, 0, SEEK_END);
 file_size = ftell(fp);
 rewind(fp);

 //allocate memory to contain the whole file size
 buffer = new char[file_size];

 if (buffer == NULL) { fputs("Cannot allocate memory space",stderr); exit(2); }

 //copy the file into the buffer
 result = fread(buffer, 1, file_size, fp);
 if (result != file_size) { fputs("Reading error",stderr); exit(3); }

 cout<<buffer;
 fclose(fp);
 delete buffer;
 }
+6  A: 

You are not zero-terminating your buffer, so it's not a valid C/C++ string.

Try the following changes:

//allocate memory to contain the whole file size, plus one char for termination
buffer = new char[file_size + 1];

if (buffer == NULL) { fputs("Cannot allocate memory space",stderr); exit(2); }

//copy the file into the buffer
result = fread(buffer, 1, file_size, fp);
if (result != file_size) { fputs("Reading error",stderr); exit(3); }

// terminate buffer, so it becomes a valid string we can print

buffer[file_size] = '\0';    
cout<<buffer;
unwind
thanks alot !!!
kaycee
A: 

buffer must contain a NULL terminated string for your cout<<buffer output to make sense.

jldupont
+4  A: 

Allocate one more place for termination character. And put it at the end of your buffer. This will probably solve your problem.

buffer = new char[file_size + 1];
buffer[file_size] ='\0';
Birkan Cilingir
A: 

When you are in C++, what speaks against using C++?

see: http://www.cplusplus.com/doc/tutorial/files/

edit2: in response to Neil (the initial version printed an empty line 0):

int main () {
        std::ifstream i ("main.cpp");
        std::string str;
        for (int line=0; getline (i, str); ++line) {
                std::cout << line <<  ':' << str << '\n';
        }
}
phresnel
If you suggest using C++, it's probably a good idea to post code that works. Imagine what happens if the file is empty. You should never use eof(), but instead base your read loop on the return value of getline().
anon
@Neil Butterworth: Nothing bad happens at least, except that 0 characters are read. But I'll add a better version.
phresnel
It prints a non-existent empty line. And you don't need to good() either.
anon
"Imagine what happens if the file is empty" (shudder), and then: 'It prints nothing'. Wonderful.Also, my initial example was not really wrong when one considers that every text editor will print a line zero, even for totally empty files. Maybe before you start nitpicking unwrong answers, give a better one yourself.
phresnel
@phresnel: Just say thank you and fix the mistake no need to be rude when it is obvious that your code was broken. In the case of empty file a blank line is printed and a normal file the last line is printed twice. It may seem trivial but its bugs like this that are hard to find and cause the most problems especially when your code is part of a larger set of applications that need to work together. Either do it correctly or don't bother.
Martin York
@Martin York: Thank you for that explanation, but I don't feel like explicitly thanking Neil for his non-argumentation ("imagine what could happen" is not an argument) (I think I showed enough appreciation by mentioning that I have fixed my code according to him).
phresnel
@Martin York: Anyways, I think it also not less dangerous to fix the OP's code, instead of suggesting the C++ way (surely apart from my initial code being wrong).
phresnel