• 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
Paul C Skertich

How dangerous is returning a initialized pointer in C++?

22 posts in this topic

A quick question on how danagerous this would actually be...

 

In a static library i have this function that will be the starting base for my engine.

_declspec(dllexport) struct EngineAPI {

public: 
EngineAPI(); 
~EngineAPI();

EngineAPI *Create();

private:

};
//-- EngineAPI.cpp
EngineAPI *EngineAPI::Create() {
EngineAPI *engine = new EngineAPI();
return engine;
}


//-- In Dynamic Library to be interpoled in C#.
EngineAPI *gEngine;
void CreateEngine() {
gEngine = gEngine->Create();
if(gEngine == nullptr) {
//-- we have problem
}
else {
//-- We are good to go.
 }
}

I just want to know because it's working for me but on this other question\answer forum they literally jumped on me saying that code was dangerous and absolutely horrendous. I'm just wanting to know why they would consider that?

0

Share this post


Link to post
Share on other sites

Okay, I don't quite understand why you are doing things this way.  You declare a global pointer, then use it to initialize the same global pointer.  Why?  if gEngine is not allocated, then calling ::Create is just going to crash.

 

I use C++ myself, but this is how I would do it instead.

void CreateEngine()
{
   gEngine = new EngineAPI();

   /* Do error checking here */
}

What you are doing appears to be quite unnecessary.  Is there a particular reason you want your engine this way?

 

Shogun.

 

EDIT: One more detail.  If you are returning an initialized pointer from C++ to C#, that is a bad idea.  C++ has it's own code routines for initializing a pointer via "new", whereas C# is undoubtedly different, so calling delete on a C++ pointer in C# is potentially dangerous.  Think of it this way, would you use malloc() for a C pointer, then deallocate it with delete in C++?  That is a VERY bad idea, and I would not recommend it.

Edited by blueshogun96
1

Share this post


Link to post
Share on other sites

Okay, that would make a lot of sense! Well inside the API I wanted to have the engineAPI do most most of the handling. It's not it's crashing - it's just the correctedness of good programming is why the people on that q/a forum was getting hysterical about. I get what you're saying. For instance I wanted everything to be based from the engine or to be branching from the engine.

 

So, I believe from going back and forth to the static library to the dynamic library for interloping to C# I'm getting a bit mixed up. An API\SDK are just tools either interfaces, abstract classes and a like - am I correct maybe not on the terminology but the basis of it.

 

Maybe my brain isn't making sense lol! You know how NVIDIA creates a physics scene I don't recall using a new keyword. I switched to bullet physics because I can't compile the nvidia physics library along with my static library file then import the static library into my dynamic library.

 

Yeah you're right it doesn't make much sense why i would be calling the Create() function because it's just like saying the new keyword like you mentioned.

0

Share this post


Link to post
Share on other sites

I thought I just ask because the stackexchange site wasn't so happy about my question. Instead of the Create() function I just am using the EngineAPI *engine = new APIEngine(). approach. It's not too bad just have to remember to place a delete engine when I'm done. Which I've already have done when the editor closes. When it gets down to the creating the game finally - I'll make sure I check every possibly memory leak. I know how it is to open a program then to close it - then to reopen the program again and it hangs a bit or suddenly just start spitting out exceptions.

 

That's one more thing I've been working on keeping sure everything is leak free and code is readible so i can understand it when I'm looking back at the code for any improvements.

0

Share this post


Link to post
Share on other sites

Also what came to mind is if I stuck with the whole Create function and when I need to dispose it - there will possibly be a memory leak most definately. As Buckeye stated. It's always to stay safe than sorry later on when testing on other platforms.

0

Share this post


Link to post
Share on other sites

 

You wouldn't need to call delete if you would do:

auto engine = std::make_unique<APIEngine>();

I haven't got to smart pointers yet but still I would need the engine pointer for later referencing until the program closes.

0

Share this post


Link to post
Share on other sites

 

 

You wouldn't need to call delete if you would do:

auto engine = std::make_unique<APIEngine>();

I haven't got to smart pointers yet but still I would need the engine pointer for later referencing until the program closes.

 

What I'm trying to do is create a proper framework for the Engine's API. The Engine API is at the parent or root node for instance and all it's counter parts are in the children node. Graphics API is under the Engine's API under the Graphic's API goes in the model rendering and so on and so on. A neat looking heiarchy tree. My framework now is going through re-working.

0

Share this post


Link to post
Share on other sites

 

 

You wouldn't need to call delete if you would do:

auto engine = std::make_unique<APIEngine>();

I haven't got to smart pointers yet but still I would need the engine pointer for later referencing until the program closes.

 

 

That's what std::unique_ptr::get() is for: to get the pointer to the object managed by the unique_ptr without releasing ownership of the pointer.

 

This tutorial about C++11 smart pointers is worth a read.

1

Share this post


Link to post
Share on other sites

 

 

 

You wouldn't need to call delete if you would do:

auto engine = std::make_unique<APIEngine>();

I haven't got to smart pointers yet but still I would need the engine pointer for later referencing until the program closes.

 

 

That's what std::unique_ptr::get() is for: to get the pointer to the object managed by the unique_ptr without releasing ownership of the pointer.

 

This tutorial about C++11 smart pointers is worth a read.

 

Actually, I think I'm starting to fall in love with smart pointers! I always loved the smart ones. At first it was confusing because I wanted to get the functions I made within that class or struct - you know? I never knew how until I read the tutorial about C++ 11 smart tutorials. I was a bit naive about the std::shared_ptr. So, I tried it on the graphics device struct and there was no worries about ever freeing up the initialized class - just had to dispose the COM objects created by DIrectX. Pretty sweet!

0

Share this post


Link to post
Share on other sites

What are you trying to accomplish with this design?  You could just as easily stack allocate the EngineAPI object in your main function, and then pass around a pointer to that object.  This would control the timing of the object creation, it would trivially ensure that the object is destroyed when it goes out of scope, and there is no question of ownership or shared ownership.  I usually default to the simplest solution with the fewest strings attached to it, and unless you have a good reason to hide the object creation behind a factory/singleton hybrid method, I think you are unnecessarily complicating this!

ALl I'm trying to do is making the framework a bit more tidy then I think it is. In a framework shouldn't everything be interchangablly connected as in a car engine or even a tree? I'm probably like you said am putting too much thought in this framework design. I don't think the main ENgineAPI will be a singleton class. The way I see it as of right now - everything's fine I just have a habit of reworking on or redesigning on idea I have.

0

Share this post


Link to post
Share on other sites

 

What are you trying to accomplish with this design?  You could just as easily stack allocate the EngineAPI object in your main function, and then pass around a pointer to that object.  This would control the timing of the object creation, it would trivially ensure that the object is destroyed when it goes out of scope, and there is no question of ownership or shared ownership.  I usually default to the simplest solution with the fewest strings attached to it, and unless you have a good reason to hide the object creation behind a factory/singleton hybrid method, I think you are unnecessarily complicating this!

ALl I'm trying to do is making the framework a bit more tidy then I think it is. In a framework shouldn't everything be interchangablly connected as in a car engine or even a tree? I'm probably like you said am putting too much thought in this framework design. I don't think the main ENgineAPI will be a singleton class. The way I see it as of right now - everything's fine I just have a habit of reworking on or redesigning on idea I have.

 

I'm not saying it is right or wrong - I'm just saying that it would be simpler and more safe if you stack allocate the object instead of the method you showed above.  There is no more or less dependencies on the implementation of your object in either method, so like I mentioned above, I would tend toward the simplest alternative.

0

Share this post


Link to post
Share on other sites

 


Actually, I think I'm starting to fall in love with smart pointers! I always loved the smart ones. At first it was confusing because I wanted to get the functions I made within that class or struct - you know? I never knew how until I read the tutorial about C++ 11 smart tutorials. I was a bit naive about the std::shared_ptr. So, I tried it on the graphics device struct and there was no worries about ever freeing up the initialized class - just had to dispose the COM objects created by DIrectX. Pretty sweet!
Smart pointers are a great tool, but remember what they are implying - they implement ownership semantics for the object they are wrapping.  If you have a shared pointer to your engine API object, then you are essentially saying that any object that has a reference to it is also an owner of it.  That means that if you have one outstanding reference, the object will not be destroyed.

 

That can be what you want in many cases, but the usage you point out above is not really one of those (at least in my humble opinion!).

 

I'll have to keep that in mind! I don't want this to drag on further because it wasn't my intention. If I'm going to use a smart pointer it may as well be on something that I want to get rid of when it's out of scope or something that isn't referenced a lot of times?  

0

Share this post


Link to post
Share on other sites

All the discussion about smart pointers is great. However, it is possible to make the original code safe (or safer) without using smart pointers. You need to use a static function for Create, instead of a standard function. A static function is part of the class, but doesn't access any of the class members, and thus is safe to use even if you don't have an instantiated object. So, change:

EngineAPI *Create();

To:

static EngineAPI *Create();

And change:

gEngine = gEngine->Create();

To:

gEngine = EngineAPI::Create();

Again, all the smart pointer and ownership discussion is great, but static Create functions are a pattern you'll often see, and are perfectly valid.

 

Geoff

Edited by gdunbar
1

Share this post


Link to post
Share on other sites
To make things even better, you could use Meyers Singleton (you're trying to accomplish a singleton, are you not?). It has the advantage of being thread-safe (in C++11), plus: you don't have to use dynamic memory to allocate it, you don't have to always check if you have already allocated it (gEngine != null) and you don't have to deallocate it. It automatically calls your destructor upon program exit.
 
static EngineAPI * EngineAPI::Create() {
  static EngineAPI engineAPI;
  return &engineAPI;
} 
-1

Share this post


Link to post
Share on other sites

 

You wouldn't need to call delete if you would do:

auto engine = std::make_unique<APIEngine>();

Although the intent is good, that is usually not a great idea (just like deleting the pointer in general isn't). You should always have a Create function paired with a Destroy (or similarly named) function. That one can be called from a custom deleter if you'd like to use unique_ptr, of course.

 

Why?

 

First, it makes opaque what's going on. It allows you to later change how the library starts up and tears down without having to modify client code. Even if Destroy simply calls delete for now, you still want to encapsulate that. You can change whatever happens behind the scenes without asking someone.

 

Second, and more importantly, on some systems (notably one major desktop operating system), shared libraries have (or may have) their own heap.

Which means that you may end up allocating the Engine object on one heap and attempt to free it on another, which the runtime might swallow silently, or it might answer with a debug assert, or something different. In any case, it's not a pretty thing, even if it "works fine".

0

Share this post


Link to post
Share on other sites


Second, and more importantly, on some systems (notably one major desktop operating system), shared libraries have (or may have) their own heap.
All the more reason for stack allocation!
2

Share this post


Link to post
Share on other sites

wow I got back a lot of great feedback from everyone! samoth this makes sense because the library file could create an allocated memory address at a certain spot in memory and when sometimes the DLL retreives it - it says causes an exception of unable to read or write to memory location. This is happening to the font system that I got from Rastertek. I plan on reduing the font system because if I leave the room for one minute and I have important level detail I want to save- then my work is done due to the exception. Happens when I'm mapping the dynamic buffer. I'll get to that later on not on this post though.

 

As of now I'm continuing reading and doing more research on how I can improve upon my C++ skills with less mistakes. If someone's playing my game and it suddenly burps up a exception - it's going to leave many customers unhappy and unwilling to buy from me again. That I do know that's why I'm taking every precaution and every step to assure my skills become better sharpened.

0

Share this post


Link to post
Share on other sites

One thing I know about business is a customer that is unhappy won't return again and will have harder time trusting the next product. I understand games like Rage have bugs that left a lot of players aggravated. Some logical errors such as collision detection (e.g. going through a rock and being stuck in a rock) are something things that aren't avoidable. Or spawning at the wrong time and wrong place like enemies in the grown - caught that glitch in Assassin's Creed 4.  However, if I have my game constantly crashing on the players - my head will be on the platter and I may as well dig myself into a cave; so to speak.

 

I'm not saying I'm a total noobie but I do need to sharpen my skills like a knife that needs sharpen every once in a while - if I'm going to compete in the game industry.

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