This topic is 2113 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I wonder if such style of coding is okay in c and how to do that,

let me explain I want load disk file into ram with just one function

call of my production

I defined

struct bytes

{

char* begin;

char* end;  //end is a first char after the data

}

the function mallocs appriopriate ram ant then reads whole file into

it and thats all

 int get_file_size(FILE* file)
{
int seek_pos = ftell(file);
fseek(file, 0, SEEK_END);
int file_length = ftell(file) ;
fseek(file, seek_pos, SEEK_SET);

return file_length;
}

{
FILE * file = fopen(file_name, "rb");

int file_length = get_file_size(file);
char* data      = malloc(file_length);

if(data == NULL)   ERROR_EXiT("\n could not malloc data for file");

int error = fclose(file);

if(error)  ERROR_EXIT("error closing file %s", file_name);

bytes loaded_bytes = {data, data + file_length};

}

ERROR_EXIT() is just a function wrapper on printf and also cals exit(1)

the questions:

1) is this genrerally correct (reasonable way of coding)?
2) what with names? specificaly is the name bytes for such chunk of ram ok
3) can it be in some way improved?

##### Share on other sites

I'd pass back the data and size rather than a begin and end pointer. This makes it clear you didn't allocate memory for end. And data size is usually more useful than an end pointer anyways.

Bytes isn't the best name, but it's not the worst either. Seeing bytes as a data type, I would incorrectly assume it's just a byte[] or such at first glance.

##### Share on other sites

I'd pass back the data and size rather than a begin and end pointer. This makes it clear you didn't allocate memory for end. And data size is usually more useful than an end pointer anyways.

Bytes isn't the best name, but it's not the worst either. Seeing bytes as a data type, I would incorrectly assume it's just a byte[] or such at first glance.

as to size instead of end i am not sure, also as to name bytes

i am not sure too, it is about some chunk of ram, hard to decide what name to use - it should be common name good for common acceptance becouse this is some low level based type

as to fread tnx i moslooked that

i am also not sure if i could give three parts info error or just only one

for example

if(file == NULL)     ERROR_EXIT("\n cannot open file %s \n fopen(\"%s\", \"rb\") returns NULL \n  file: %s  line %d ", file_name, file_name, __FILE__, __LINE__);

gives the output

ERROR:
cannot open file input.txt
fopen("input.txt", "rb") returns NULL
file: main.c  line 60

program exit

not sure if i should give the failed function call line and also
code location info as an output..

##### Share on other sites

if(file == NULL) ERROR_EXIT("%s(%d) cannot open file '%s': %s\n", __FUNCTION__, __LINE__, file_name, strerror(errno));

That gives pretty much all the information you need.  Giving the source line and the args to the call and the fact that it's indicated failure when there's a failure is useless redundancy, but the reason for the failure is the most useful thing and you're missing it.

Note I also put quotes around the filename so it's obvious it's empty (or contains nonprintable characters).  You'll need to include <string.h> and <errno.h> to get the appropriate declarations for strerror() and errno.

##### Share on other sites

if(file == NULL) ERROR_EXIT("%s(%d) cannot open file '%s': %s\n", __FUNCTION__, __LINE__, file_name, strerror(errno));

That gives pretty much all the information you need.  Giving the source line and the args to the call and the fact that it's indicated failure when there's a failure is useless redundancy, but the reason for the failure is the most useful thing and you're missing it.

Note I also put quotes around the filename so it's obvious it's empty (or contains nonprintable characters).  You'll need to include <string.h> and <errno.h> to get the appropriate declarations for strerror() and errno.

but i would like to use one 'global' ERROR_EXIT(...) function for all my erroring purposes (called after all whole program failed function fails and other wrong conditions detected ) - the "strerror(errno)" would then behave correctly? what is scope of this information - only c standard lib? never used it

Edited by fir

##### Share on other sites

but i would like to use one 'global' ERROR_EXIT(...) function for all my erroring purposes (called after all whole program failed function fails and other wrong conditions detected ) - the "strerror(errno)" would then behave correctly? what is scope of this information - only c standard lib? never used it

The macro is declared in a header somewhere, put the required #include's in it too. They will be pulled into every unit that happens to use the macro, which is precisely when they will be needed.

Note I would only use this for debugging purposes during development. It is better style (but not the only possibility, of course) to use a more structured form of error handling where errors are handled by the appropriate function along the call stack (eventually bubbling up to the user in the form of a sane error message the user can understand with optional guru meditation, though it can be handled at a lower level if a given function expects an error it can react to in a safe way) instead of crashing the program instantly. For library code it is completely unacceptable to crash the host program.

##### Share on other sites

I would change it slightly, my main issue with the original is that the function call leaves it up-to the caller to free the memory and the allocation is also hard-inlined within the call. Thus there's no way of changing the allocation and the caller may expect the memory to be allocated in a different way and thus free it incorrectly. For example, if the caller tries to release the memory with delete rather than free, the function as is just expects the caller to know what to do. I realise it's a personal project, but 6 months down the line you may be the one who forgets :)

I would change it so the function is passed either an allocator or a buffer object. for example:

(pseudo-code)

int read_file_and_alloc_bytes( MemoryBuffer &buffer, const char *fileName )
{
buffer.Allocate( file_size );
}



Which means allocation and release are now managed by the MemoryBuffer object, it also allows the memory buffer to have different implementations with different memory behaviour etc.

n!

Edited by nfactorial

##### Share on other sites

I would change it slightly, my main issue with the original is that the function call leaves it up-to the caller to free the memory and the allocation is also hard-inlined within the call. Thus there's no way of changing the allocation and the caller may expect the memory to be allocated in a different way and thus free it incorrectly. For example, if the caller tries to release the memory with delete rather than free, the function as is just expects the caller to know what to do. I realise it's a personal project, but 6 months down the line you may be the one who forgets

I would change it so the function is passed either an allocator or a buffer object. for example:

(pseudo-code)

int read_file_and_alloc_bytes( MemoryBuffer &buffer, const char *fileName )
{
buffer.Allocate( file_size );
}



Which means allocation and release are now managed by the MemoryBuffer object, it also allows the memory buffer to have different implementations with different memory behaviour etc.

n!

somewhat good point but this is then some digression because

it is not c ... if so it seems that you can do it simpler by

buffer.read_file("filename.txt");
buffer.free();


in c i got two separate functions instead

##### Share on other sites

Either pass a user allocated buffer (so they allocate and free it) or have 2 functions: 1 to alloc and read and another to free the memory returned from the alloc and read function. It doesn't matter if the free function just calls free on the buffer it should still be a separate function so if you do change the allocation implementation you only need to change the freeing function.

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 18
• 34
• 9
• 16
• 22