• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
fir

bytes data = read_file_and_alloc_bytes("data.txt");

8 posts in this topic

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;
 }
 
 bytes read_file_and_alloc_bytes(char* file_name)
 {
  FILE * file = fopen(file_name, "rb");
   if(file == NULL)      ERROR_EXIT("\n input file %s not found", file_name);
 
  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 elements_read = fread(data, 1, file_length, file);
  int error = fclose(file);
 
  if(error)  ERROR_EXIT("error closing file %s", file_name);
 
  bytes loaded_bytes = {data, data + file_length};
 
  return loaded_bytes;
}
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?
 
0

Share this post


Link to post
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.

 

You don't check that fread actually read the bytes, so you could improve your code by making sure fread actually succeeded.

0

Share this post


Link to post
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.

 

You don't check that fread actually read the bytes, so you could improve your code by making sure fread actually succeeded.

 

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..
 
0

Share this post


Link to post
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.

0

Share this post


Link to post
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
0

Share this post


Link to post
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.

0

Share this post


Link to post
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 );
    return read( buffer.rawBuffer, 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
0

Share this post


Link to post
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 smile.png

 

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 );
    return read( buffer.rawBuffer, 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

0

Share this post


Link to post
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.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0