hi all,
I'm new to the linux programming first of all.

I just wrote this program.

#include <fcntl.h>
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std ;

int main(int argc,char **argv)
{
	/* open the file */
	string _path_name = "./file";
	string _return ;
	int fd=open(_path_name.c_str() ,O_RDONLY);
	
	/* buffer to read the file */
	char * buffer=new char [100];
	buffer[99]=0;
	int n=99;
	while (n==99)
	{
		n=read(fd,buffer,99);
		if (n<99)
		{ 
			buffer[n]=0;
		}
		/* append them to the string _return */
		_return += (char*)buffer;
	}	
	cout << _return ;
	/* close the file */
	close(fd);
	/* unallocate the memory */
	delete *buffer;
	return 0;
}

and when I create the buffer on the stack using this.

char buffer[100];

Then it won't work properly. I mean that
_return += (char*) buffer;
statement will pass the null character 0 and print the garbage things even in the
buffer. What is the wrong with that?
But when I use the `new char[100]` it works nicely and end attaching when the 0 (null character ) found.What is the reason? can anybody explain this to me?

Any idea?

--Thanks in advance--
sanudn.

I'm not versed in the nuances of Linux, but I do know that the integer value zero (0) is not the NULL character. The NULL character is '\0'. I suspect this is part of your problem.

Well, I just tested a similar code on my Linux machine (gcc 4.4, with only default options), and it's working properly.

Maybe, just maybe, in your compiler / std-libraries, there is an additional char_traits template specialization for a static array of chars. It would be very weird and non-standard, but it could definitely produce the exact error you are describing. The reason for this is that the std::string class uses this char_traits template class to determine the number of chars that are being appended. By virtue of the template specialization for a char pointer, it will essentially call strlen() on the pointer, which will lead to correct behavior. But, if your particular system defines a specialization for the char[N] type (N being a compile-time constant), the char_traits::length() function might output N (which would be 100 in your case) and then the entire buffer would be appended to the std::string (ignoring the null-character along the way).

But I have to repeat, this _could_ explain the problem, but it is _extremely_ unlikely, at least I would be shocked to know that there is a compiler / std-library provider in Linux which results in that behavior.

Comments
this may be the case.

I'm not versed in the nuances of Linux, but I do know that the integer value zero (0) is not the NULL character. The NULL character is '\0'. I suspect this is part of your problem.

according to http://www.robelle.com/smugbook/ascii.html the null character is is the 0x00h
. If the value contain the 0x00h then this should be work.


Then I create the array on the stack using buffer[100] , like so and return to the debugger.

It's seems clearly that the compiler ignore the line 23

if ( n <99)
          buffer[n]='\0';

Clearly it seems like the compiler does ignore that statement.


Any idea.

And using '\0' instead 0 does not make any effect in the program. :(

can someone explain this?

Well, I just tested a similar code on my Linux machine (gcc 4.4, with only default options), and it's working properly.

Maybe, just maybe, in your compiler / std-libraries, there is an additional char_traits template specialization for a static array of chars. It would be very weird and non-standard, but it could definitely produce the exact error you are describing. The reason for this is that the std::string class uses this char_traits template class to determine the number of chars that are being appended. By virtue of the template specialization for a char pointer, it will essentially call strlen() on the pointer, which will lead to correct behavior. But, if your particular system defines a specialization for the char[N] type (N being a compile-time constant), the char_traits::length() function might output N (which would be 100 in your case) and then the entire buffer would be appended to the std::string (ignoring the null-character along the way).

But I have to repeat, this _could_ explain the problem, but it is _extremely_ unlikely, at least I would be shocked to know that there is a compiler / std-library provider in Linux which results in that behavior.

You'r explanation may correct and explain this situational very clearly.

so when I using a stack , does it ignore the statements like `buffer[n]=0' ?
Is this is due to prevent the bufferoverflows?

If you don't believe me I open the gdb and break at the line 24.
For my file the n=77,after and before that instruction I hit.

print (char*)buffer

but same answer !
which is something unfair. that means that compiler completely ignores that line.because we are entering null characters to the array. Is this is the case?

Any I don't generate the assembly listing,it's worth to generate the assembly list and
see how that `buffer[n]='\0';` line is actually assembled?

May be it is not grinned to any instructions.

Well, this is not a normal behavior for sure, so how to explain it?
I mean, I copy-pasted the exact code you posted (changing buffer to a static array, and taking the delete statement out) and it works perfectly.

What compiler are you using? Is it up-to-date with your linux core version?

This article has been dead for over six months. Start a new discussion instead.