I'm working with a C++ library which makes extensive use of constructs like:
FILE *out_file1, *out_file2 ... *out_fileN;
//for some output files, but not all:
out_file1 = fopen( filename, "w" )
//later
if( out_file1 ) fprintf( ... )
if( out_file2 ) fprintf( ... )
This seems to work OK under g++ on OS X. When I run it on linux, however, I get segfaults. Checking through the code, out_file is often initialised to non zero values.
I've tried adding
out_file = NULL
but this doesn't seem to help - in fact, according to the debugger, it doesn't change the value of out_file.
Can anyone help as to:
Is this a recognised and sensible way to do file IO (i.e. using the file pointers in conditionals)
Why is the value of the pointer not being set to null?
How can I set it to null?
Just to be clear - I'm trying to change the code as little as possible, as I'm coding a wrapper to someone else's library. So, even if the general structure is a strange way to do things, I'd rather find a workaround which doesn't change it if possible.
EDIT:
Since this seems to be a reasonable, if outdated way to do conditional file IO, I can narrow the scope of my question to the second two out of three, i.e.
class IO
{
private:
FILE* opFile
IO()
{
//At this point, opFile == 0x40
opFile = NULL; //At this point opFile is still 0x40
}
}
So obviously, if it comes out of the constructor with a non-null value, anything like:
if( opFile ) fprintf( ... )
will fail. But how is it managing to come out of the constructor with a non-null value?
And in case it helps, this works "as expected" under gcc on OSX, but not g++-4.3 or g++4.4 on Ubuntu.
Your problem is elsewhere in the code, most likely in the *printf calls you mention?
Show us more code, or use a debugger to find where it crashes.
g++ -O0 -Wall -g mysource.cpp -o test
gdb ./test
(gdb) run argument1 argument2
Also, look at valgrind for additional memory checking tools
valgrind ./test
$0.02
Update
Added -O0 to avoid confusing analysis with results of proper compiler optimization :)
in C++, you should use iostreams, will help you avoid all these issues...
std::ifstream in ("some_file");
if (in)
{
// do stuff with stream...
}
Is this the actual code from your program?
FILE* out_file1, out_file2 ... out_fileN
Then only out_file1 is a FILE* and all the rest are just FILE. That would explain their "funny values".
In C++ you should use std::fstream(or std::istream/std::ostream) for file-IO, unless you have a very good reason not to. Then you would most likely not have this problem, as you could just write this:
std::ifstream file("myfile.txt");
while(file) { // this checks for any error
// do stuff with file
}
Possibly the compiler is optimizing your code. Assigning out_file to NULL a moment before it gets assigned to by the return value of fopen is pointless. The compiler might know that and not bother assigning NULL.
You could define and initialize the value on one line:
FILE* out_file = fopen( filename, "w" )
But, this won't make your problem go away. As somebody commented, you might be looking at the wrong bit of code as there doesn't appear to be much wrong with this.
You could try creating a minimal app that does just the operation you want and see if that works ok before reintroducing the rest of the code.
Related
Is it possible to have a function like this:
const char* load(const char* filename_){
return
#include filename_
;
};
so you wouldn't have to hardcode the #include file?
Maybe with a some macro?
I'm drawing a blank, guys. I can't tell if it's flat out not possible or if it just has a weird solution.
EDIT:
Also, the ideal is to have this as a compile time operation, otherwise I know there's more standard ways to read a file. Hence thinking about #include in the first place.
This is absolutely impossible.
The reason is - as Justin already said in a comment - that #include is evaluated at compile time.
To include files during run time would require a complete compiler "on board" of the program. A lot of script languages support things like that, but C++ is a compiled language and works different: Compile and run time are strictly separated.
You cannot use #include to do what you want to do.
The C++ way of implementing such a function is:
Find out the size of the file.
Allocate memory for the contents of the file.
Read the contents of the file into the allocated memory.
Return the contents of the file to the calling function.
It will better to change the return type to std::string to ease the burden of dealing with dynamically allocated memory.
std::string load(const char* filename)
{
std::string contents;
// Open the file
std::ifstream in(filename);
// If there is a problem in opening the file, deal with it.
if ( !in )
{
// Problem. Figure out what to do with it.
}
// Move to the end of the file.
in.seekg(0, std::ifstream::end);
auto size = in.tellg();
// Allocate memory for the contents.
// Add an additional character for the terminating null character.
contents.resize(size+1);
// Rewind the file.
in.seekg(0);
// Read the contents
auto n = in.read(contents.data(), size);
if ( n != size )
{
// Problem. Figure out what to do with it.
}
contents[size] = '\0';
return contents;
};
PS
Using a terminating null character in the returned object is necessary only if you need to treat the contents of the returned object as a null terminated string for some reason. Otherwise, it maybe omitted.
I can't tell if it's flat out not possible
I can. It's flat out not possible.
Contents of the filename_ string are not determined until runtime - the content is unknown when the pre processor is run. Pre-processor macros are processed before compilation (or as first step of compilation depending on your perspective).
When the choice of the filename is determined at runtime, the file must also be read at runtime (for example using a fstream).
Also, the ideal is to have this as a compile time operation
The latest time you can affect the choice of included file is when the preprocessor runs. What you can use to affect the file is a pre-processor macro:
#define filename_ "path/to/file"
// ...
return
#include filename_
;
it is theoretically possible.
In practice, you're asking to write a PHP construct using C++. It can be done, as too many things can, but you need some awkward prerequisites.
a compiler has to be linked into your executable. Because the operation you call "hardcoding" is essential for the code to be executed.
a (probably very fussy) linker again into your executable, to merge the new code and resolve any function calls etc. in both directions.
Also, the newly imported code would not be reachable by the rest of the program which was not written (and certainly not compiled!) with that information in mind. So you would need an entry point and a means of exchanging information. Then in this block of information you could even put pointers to code to be called.
Not all architectures and OSes will support this, because "data" and "code" are two concerns best left separate. Code is potentially harmful; think of it as nitric acid. External data is fluid and slippery, like glycerine. And handling nitroglycerine is, as I said, possible. Practical and safe are something completely different.
Once the prerequisites were met, you would have two or three nice extra functions and could write:
void *load(const char* filename, void *data) {
// some "don't load twice" functionality is probably needed
void *code = compile_source(filename);
if (NULL == code) {
// a get_last_compiler_error() would be useful
return NULL;
}
if (EXIT_SUCCESS != invoke_code(code, data)) {
// a get_last_runtime_error() would also be useful
release_code(code);
return NULL;
}
// it is now the caller's responsibility to release the code.
return code;
}
And of course it would be a security nightmare, with source code left lying around and being imported into a running application.
Maintaining the code would be a different, but equally scary nightmare, because you'd be needing two toolchains - one to build the executable, one embedded inside said executable - and they wouldn't necessarily be automatically compatible. You'd be crying loud for all the bugs of the realm to come and rejoice.
What problem would be solved?
Implementing require_once in C++ might be fun, but you thought it could answer a problem you have. Which is it exactly? Maybe it can be solved in a more C++ish way.
A better alternative, considering also performances etc., to compile a loadable module beforehand, and load it at runtime.
If you need to perform small tunings to the executable, place parameters into an external configuration file and provide a mechanism to reload it. Once the modules conform to a fixed specification, you can even provide "plugins" that weren't available when the executable was first developed.
I've read a few threads that said I should close a certain file when this error pops up when I use cppcheck. But my issue is this:
2 weeks back I ran a shell script which called another file inside it to execute and it worked fine.
But for the past two days, I got segmentation fault in when running the main code using Cygwin. I had posted about it earlier, and then on analysing the executable file (in cpp) using cppcheck, I got a line 31 resource leak : fin.
This particular block of code is pasted:
void load_fasta_list(char * file_name, vector<string> &file_list){
FILE * fin;
fin = fopen(file_name, "rt");
char temp_file[512];
char * temp_file2;
while (!feof(fin)){
fgets(temp_file, 512, fin);
if (!feof(fin)){
temp_file2 = strtok(temp_file, "\n");
file_list.push_back(temp_file2);
}
}
cout<<file_list.size()<<" FASTA files to be analyzed."<<endl;
}
The line 31 is the last bracket there.
These codes are available from Washington U which I am using (and I am a beginner), and I am getting this error without having done anything to the set of codes.
Any idea on how to progress?
P.S. When I tried the fclose statement, cppcheck showed no error, but when I ran the shell script again, I got the segmentation fault
The problem is that your lecturer taught you C instead of C++. He used a primitive C construct to open a file which must be manually closed instead of the automatic cleanup offered by C++. He forgot to do so, aptly demonstrating why using such constructs is inherently unsafe. It is also exception-unsafe, and there are other unpleasant potential bugs lurking in here such as off-by-one errors, and the fun which is non-reentrant strtok, due to the use of C string handling.
You should rewrite it (or make your lecturer fix it) to use the equivalent C++ constructs, which automatically clean up all the memory and file handles needed.
The code contains other offences too, like the output parameter, using namespace std;, and such. Whoever wrote it is simply unfit to teach C++. You need to kick them into gear.
To prevent a leak, call
fclose(fin);
This call will close the file.
I see two problems:
Check to see that fin is valid (fopen returns a null if the file doesn't exist!)
Use fclose(fin) to close your file
I am a bit lost working with the following piece of code:
T_TERM_LIST term_list = term_list_one($1);
term_list = term_list_add(term_list, $3);
T_TERM term_equality = term_app(str_make("="), term_list);
T_TERM_LIST term_list_2 = term_list_one(term_equality);
$$ = term_app(str_make("not"), term_list_2);
printf("\n100 \n");
My question is regarding the last line, if I leave the printf statement it works as expected else if I remove the printf line I get a null pointer exception, I would like to understad what is ging on there.
As a matter of adding information the datatypes used are typedefs of unsigned and list of unsigned.
In addition The code is embedded into a YACC file which may explain the symbols $n in the shared piece of code code.
As #chux advised me I copy & paste my comment as the answer to my question. Actually it is a kind of lessons learned.
I found out that the code compiled by make clean; make is different of the code compiled by make clean; make debug which adds all the flags for debugging. The results for the former are the expected whereas the null pointer reference is obtained in the later case. So I think we can finish this question by pointing that using valgring and gdb is a good choice in order to solve the problem I posed.
Thanks a lot!
There is a function to load files:
int loadfile(char *fn)
{
printf( "\n my path: '%s' \n", fn );
FILE *f = fopen( fn, "r");
printf( "got\n" );
...
return 1;
}
The first file is in main() newfile( argv[1] );, works. The second is get by flex parsing/reading the first file, what I belive isn't related to the problem.
The console:
path: 'file1.hot'
got
path: 'file2.hot'
Segmentation fault: 11
The printf was able to print the char *fn, but fopen get a segmentation fault.
The next situation was, I tried explicit to put the file inside the loadfile doing fopen( "file2.hot", "r"); and works.
I'm compiling with g++, there is a different approaching when using c++ to use char * or fopen?
EDIT
Sorry, there's no newfile( argv[1] );. Correct: loadfile( argv[1] );.
General remark: When using C++, please prefer std::fstream to the C-style fopen/fread/etc.; also prefer std::string to char*. The latter alone will cure many memory headaches. If you, for some reason, have to stick to the C-style functions, be sure to check the return values (as mentioned in the other answers here already) - fopen for example returns a NULL pointer when it fails.
More specific to your question: Try to run your program under gdb (e.g. gdb <your-program>), to see where the Segmentation fault occurs exactly; that way you will also be able to see more details (e.g. variable contents etc.). Alternatively, if working under linux, use analysis tools such as valgrind to detect any kind of memory access problems.
you should always check return values from functions that have a return value. In this case make sure when you fopen the file that the return handle is not NULL and also make sure if you open the file, to fclose it.
Learn to use the GDB debugger (assuming you are on Linux), or the valgrind utility.
Perhaps putting your file path inside a std::string is worthwhile, and, as nyarlathotep mentioned, use a std::fstream.
It could happen that your fn is not null terminated....
Compile with g++ -Wall -g
As Anders K answered, always check the result of fopen against NULL. Pierre Vittet's Talpo extension to GCC (coded in MELT) is able to check automatically that you do check that.
I see C's getcwd via:
man 3 cwd
I suspect C++ has a similar one, that could return me a std::string .
If so, what is it called, and where can I find it's documentation?
Thanks!
Ok, I'm answering even though you already have accepted an answer.
An even better way than to wrap the getcwd call would be to use boost::filesystem, where you get a path object from the current_path() function. The Boost filesystem library allows you to do lots of other useful stuff that you would otherwise need to do a lot of string parsing to do, like checking if files/directories exist, get parent path, make paths complete etcetera. Check it out, it is portable as well - which a lot of the string parsing code one would otherwise use likely won't be.
Update (2016): Filesystem has been published as a technical specification in 2015, based on Boost Filesystem v3. This means that it may be available with your compiler already (for instance Visual Studio 2015). To me it also seems likely that it will become part of a future C++ standard (I would assume C++17, but I am not aware of the current status).
Update (2017): The filesystem library has been merged with ISO C++ in C++17, for
std::filesystem::current_path();
std::string's constructor can safely take a char* as a parameter. Surprisingly there's a windows version too.
Edit: actually it's a little more complicated:
std::string get_working_path()
{
char temp[MAXPATHLEN];
return ( getcwd(temp, sizeof(temp)) ? std::string( temp ) : std::string("") );
}
Memory is no problem -- temp is a stack based buffer, and the std::string constructor does a copy. Probably you could do it in one go, but I don't think the standard would guarantee that.
About memory allocation, via POSIX:
The getcwd() function shall place an absolute pathname of the current working directory in the array pointed to by buf, and return buf. The pathname copied to the array shall contain no components that are symbolic links. The size argument is the size in bytes of the character array pointed to by the buf argument. If buf is a null pointer, the behavior of getcwd() is unspecified.
Let's try and rewrite this simple C call as C++:
std::string get_working_path()
{
char temp [ PATH_MAX ];
if ( getcwd(temp, PATH_MAX) != 0)
return std::string ( temp );
int error = errno;
switch ( error ) {
// EINVAL can't happen - size argument > 0
// PATH_MAX includes the terminating nul,
// so ERANGE should not be returned
case EACCES:
throw std::runtime_error("Access denied");
case ENOMEM:
// I'm not sure whether this can happen or not
throw std::runtime_error("Insufficient storage");
default: {
std::ostringstream str;
str << "Unrecognised error" << error;
throw std::runtime_error(str.str());
}
}
}
The thing is, when wrapping a library function in another function you have to assume that all the functionality should be exposed, because a library does not know what will be calling it. So you have to handle the error cases rather than just swallowing them or hoping they won't happen.
It's usually better to let the client code just call the library function, and deal with the error at that point - the client code probably doesn't care why the error occurred, and so only has to handle the pass/fail case, rather than all the error codes.
You'll need to just write a little wrapper.
std::string getcwd_string( void ) {
char buff[PATH_MAX];
getcwd( buff, PATH_MAX );
std::string cwd( buff );
return cwd;
}
I used getcwd() in C in the following way:
char * cwd;
cwd = (char*) malloc( FILENAME_MAX * sizeof(char) );
getcwd(cwd,FILENAME_MAX);
The header file needed is stdio.h.
When I use C compiler, it works perfect.
If I compile exactly the same code using C++ compiler, it reports the following error message:
identifier "getcwd" is undefined
Then I included unistd.h and compiled with C++ compiler.
This time, everything works.
When I switched back to the C compiler, it still works!
As long as you include both stdio.h and unistd.h, the above code works for C AND C++ compilers.
All C functions are also C++ functions. If you need a std::string, just create one from the char* that getcwd gets for you.
I also used boost::filesystem as stated in another answer above. I just wanted to add that since the current_path() function does not return a std::string, you need to convert it.
Here is what I did:
std::string cwd = boost::filesystem::current_path().generic_string();
You could create a new function, which I would prefer over linking to a library like boost(unless you already are).
std::string getcwd()
{
char* buff;//automatically cleaned when it exits scope
return std::string(getcwd(buff,255));
}