I can write a function this way in Objective-C. This can be used to churn out many UIButtons.
+(UIButton*)getButton:(CGRect)frame{
UIButton *button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:#"Some title" forState:UIControlStateNormal];
button.frame=frame;
return button;
}
Can the same be done in C++? I am not asking about creation of UIButton in C++.
But churning out many objects with a help of a function as this:
CString getCstring(some parameters)
{
CString string = L"Hi sampe string.";
return string;
}
I think that the CString object that is created in this function would be in stack and may lose it value once goes out of this function.
In case of Objective-C code, we can retain the autoreleased object to use it. Is there any such mechanism available in C++?
In C++ you can do
CString* getCString(some parameters)
{
CString* string = new CString(L"Hi sample string.");
return string;
}
and delete (by calling delete on the pointer) the string in the caller after he is done with it if you want to have the string on the heap. However in the first version you posted, I see no problem. It is a stack variable, but of course it is still valid in the caller as it is the return value.
I think that the CString object that is created in this function would be in stack and may lose it value once goes out of this function.
It doesn’t lose its value since it will be copied (although the compiler can elide the copy as an optimization).
So don’t worry – this works just fine in C++.
You can also return a pointer to dynamically allocated memory but this makes usage harder since the client has to free the memory explicitly. In general this is not a good solution – handling raw pointers to dynamic memory is the #1 reason for memory leaks and cleaning such code up is horrible.
A better way is to use smart pointers (e.g. shared_ptr or unique_ptr) that take care of the memory management themselves.
Your string variable will eventually go out of scope, but return string; will return only the copy and hence you can use it in C++ as such now...
Your Obj-C code works against coding styles and memory management rules. It should look like:
+(UIButton*)buttonWithFrame:(CGRect)aRect {
UIButton *button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:#"Some title" forState:UIControlStateNormal];
button.frame = aRect;
return button;
}
Seems like minor changes, but it makes memory managament (object ownership) obvious and names the parameter appropriately.
Related
Hello members of stackoverflow,
I'm currently trying my hands on c++ (been mostly programming in C#) and was wondering about memory management when using shared pointers.
I have a class that basicly reads in a bunch of variables from a textfile:
constructor(string file){
//..do stuff with file
s = new string(valuefromfile);
array_i = new int{value1, value2}
}
private:
shared_ptr<string> s;
shared_ptr<int*> array_i;
As far as i understood, sharedpointers help with memory allocation/leaks, since the allocated memory will be freed once all pointers are no more, without me having to deallocate them by hand, e.g. calling the classes deconstructor, or if used in a subroutine.
Now my question is
If i read in a new file with the class, "s" and "array_i" will get new values:
void readnewfile(string file){
//...do stuff with file
s = new string(newstring);
i = new int{ newvalue1, newvalue2, newvalue3 };
}
now the innitial values are not referenced anymore by those smartpointers. Will that mean the memory is freed, or do i have to watch out for something specific to prevent memory leaks?
Greetings
Thanks to Scheff for answering my question:
Shared pointer uses a reference count. If a shared pointer is overridden, the reference count of old contents is decremented (if there is one). If it reaches 0, the pointee is deleted. (I call this "Last one leaving switches the light off."-principle.) However, please, have a look at std::make_shared() which is a better replacement for new for std::shared_ptr. – Scheff
And thanks to NathanOliver for his answer:
You shouldn't need smart pointers for this at all. A std::string member and a std::vector member should be all you need. C++ is, IMHO, a lot more complex and nuanced than C#. If you are new to C++, I suggest you forget about C# and get yourself a good C++ book so you can see the C++ approach to programming, like pointers being really only needed when using polymorphism. – NathanOliver
Ye, vector is much better than redefining the arrays each time and when i read in a new File myvector.clear(); seems to do the trick without any leaks.
In my WinRT API I have to create and return HSTRING values. So far I have been using WindowsCreateString to create HSTRING value and deleting it manually with WindowsDeleteString.
WindowsCreateStringReference looks quite handy in terms one does not have to delete HSTRING manually.
You don't need to call the WindowsDeleteString function to de-allocate a fast-pass HSTRING created by the WindowsCreateStringReference function.
Can anyone elaborate on what is fast-pass string and how and when it actually gets de-allocated?
Another question that comes here is when should I prefer WindowsCreateString over WindowsCreateStringReference?
A 'fast-pass' string doesn't manage the lifetime of its string - it simply creates a wrapper around whatever underlying string you give it. This wrapper is very lightweight.
This means 2 things - firstly you don't need to delete the HSTRING (as it doesn't own the underlying string) but more importantly you must keep the underlying string alive and unchanged whilst the fast-pass string is being used.
So its useful for if you already have a string (say a const char* in the rodata section, or from another source who's lifetime is strictly greater than the lifetime of the HSTRING). But its just an optimisation to avoid a copy.
MY recommendation - if you only care about lifetime and correctly free'ing the string when done - is to use Microsoft::WRL::Wrapper::HString class which provides a nice C++ style RAII wrapper around raw HSTRING's and will correctly free them when done. Then using member functions Detach, Get, GetAddressOf, etc you can then interact with other APIs which expect raw HSTRINGs.
If you do care about speed aswell there is always a Microsoft::WRL::Wrapper::HStringReference class which duplicates the WindowsCreateStringReference funcitonality, but again with a nice c++ RAII object.
I'm wrapping part of the FBX SDK (closed, with a public API) with Mono (so COM, CLI aren't options) and a bunch of extern's, and it was all going well until I had to return a non-pointer instance. See here
The crucial point is that I have to return it back to C++ for another call. Because I don't know how you'd do that without a pointer, I returned it as such:
FBXAPI FbxProperty* Object_GetFirstProperty(FbxObject* obj)
{
return &obj->GetFirstProperty();
}
..and it's not until I try something like the next snippet that I get the "System.AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt." message.
FBXAPI const wchar_t* Property_GetName(FbxProperty* prop)
{
int c = prop->GetSrcPropertyCount();
return L"Test";
}
If I use almost identical code using the same calls in C++, it's fine. I've done another ~20 function calls in the same manner but without having to "pointerfy" it, and they're all fine too, so I don't think my DllImport's are to blame. So if the reference is to be blame, how else do I do it? Surely I don't store a global static reference somewhere just because someone called it from the API?
Any help is appreciated, C/C++ and the explicit way it handles memory is new to me.
I assume your program is crashing because the property you were getting the pointer to does no longer exist. Let me clarify and start by dissecting the following:
FBXAPI FbxProperty* Object_GetFirstProperty(FbxObject* obj)
{
return &obj->GetFirstProperty();
}
I looked up the documentation of FBX, and FbxObject::GetFirstProperty() has a return type of FbxProperty. Notice that the return value isn't any pointer or reference? That means you get a so called 'auto-variable', or in this case a 'temporary'. This kind of object only lasts until you leave the scope, which in this case is your Object_GetFirstProperty() of your wrapper. After that, the object is cleaned up and removed from the memory stack. FbxObject::GetFirstProperty() gives you a copy of the property, not an actual reference. Internally it might be different, but your wrapper is concerned about the property object itself, not it's content.
So what you are doing is you get a pointer to an address that is no longer valid later on when you pass it to your Property_GetName().
C++ behaves differently than C# in regards to object lifetime. An object in C# called MyObj can be thought of as a C++ pointer type like MyObject* - it's a like a reference value. In C# you have also value-types like struct and so forth, which are the equivalent to the C++ auto-variable. All auto-variables are destroyed when their lifetime scope is left.
What you'd have to do to overcome your problem is to save the object you get from FbxObject::GetFirstProperty() directly, and not a pointer to it. You'd basically have to marshall the object into a proper .NET class so that it's contents are not lost.
Alternatively, you could just allocate dynamic memory and copy the object you get from FbxObject::GetFirstPoperty() there, and return a pointer to your own memory. Of course you'd have to delete this memory later on manually. Here is a simple example:
FBXAPI FbxProperty* Object_GetFirstProperty(FbxObject* obj)
{
// Allocate custom memory.
char* myMem = new char[sizeof(FbxProperty)];
// Copy the property's content there.
std::memcpy(myMem, &obj->GetFirstProperty(), sizeof(FbxProperty));
// Return custom memory address.
return reinterpret_cast<FbxProperty*>(myMem);
}
This should solve your memory corruption issue. But in C++ you'd have to free this memory manually when your are finished with the property by doing ths:
FBXAPI void Property_Free(FbxProperty* prop)
{
// Free previously allocated memory
delete[] prop;
}
But this attempt may cause other problems, depending on how the actual FbxProperty handles it's data inside. You are creating a copy of the object, sure, but if the original temporaty/auto-variable deletes important memory upon destruction, you would have similar issus to the ones you have now.
If you are REALLY witty you could just write real wrapper classes for every FBX type you require and marshall the whole class type instead of generating separete C functions you have to P/Invoke every time you want to get a value or a property.
When I create a function that returns a char* or const char*, is it assumed that the calling function must deallocate the returned value when it is finished with it? Otherwise, how would it get deallocated? I'm looking some other code which calls a function that returns a char* and there is not a delete statement in the calling function. Example:
char* foo();
void bar()
{
char* result = foo();
//I should have "delete result" here right?
}
EDIT:
So In my application here is foo:
LPTSTR GetTempPath(LPCTSTR fileName)
{
LPTSTR tempPath = new TCHAR[500];
GetTempPath(500,tempPath);
printf("Temp Path %ls\n",tempPath);
PathAppend(tempPath, fileName);
_tprintf(_T("New temp path: %s\n"), tempPath);
return tempPath;
}
I wasn't sure how to write this without the new TCHAR.
I'm assuming this has to be deleted? Is there a better way to write it?
If you're using C++ and not C, you should use std::string to get rid of the problem.
There are (at least) two common conventions when a char* is returned by a function. You cannot tell which is in force without reading the documentation of the function.
The function returns a pointer to statically allocated memory. In which case the caller does not need to deallocate it.
The function returns a pointer to heap allocated memory. In which case the caller does need to deallocate it. The documentation for the function must specify how the caller must deallocate the function (free, delete etc.)
Now, since you are in charge of writing your own functions, you can choose whatever protocol you like. And in your case you should not return a char* from your functions. Choose a third way. Return a std::string and let the standard library take care of allocation and deallocation. Do it this way to make life easier for the consumer of the library.
In fact, since you are writing C++, you should be shunning char*. Sure you have to use C string when interacting with the Windows API. But leave it at that. Don't pass the pain on to the consumer of your library. Hide that complexity away.
In your situation I would make sure that you have a function that can combine two std::string instances. This could perhaps be implemented using PathAppend, but it's easy enough to roll your own. Then the only interaction you need with the Windows API is a function that returns the temporary directory in a string. That looks like this:
string GetTempDir()
{
char buff[MAX_PATH+1];
DWORD count = GetTempPath(MAX_PATH+1, buff); // I've omitted error checking
return string(buff, count);
}
The code in this function is the only code that needs to deal with C strings. You can now forget all about them in the rest of your code which can treat this as a black box. Don't let the implementation details of the lowest common denominator C interface of Win32 leak into your nicely factored C++ code.
If foo() is in an external dynamic library, the library should provide some explicit way to delete result,if delete is required, or some other way to close the working session and so on.
To answer the question you posed ("is it assumed that the calling function must deallocate the returned value when it is finished with it? Otherwise, how would it get deallocated?"):
No, the caller does not necessarily have to deallocate the string. Looking at man ctime:
char *ctime(const time_t *timep);
The return value points to a statically allocated string which might be overwritten by subsequent calls to any of the date and time functions.
Which means you do not delete nor free the string it returns.
I have a nasty bug in my C++ project. There's a class
class SomeClass {
...
std::string *someString;
...
}
Here's a constructor
SomeClass(...) {
...
someString = new std::string("");
...
}
And the thing is that afterwards I operate only with that specific string, without modifying the poiner value. I assign to that string different strings all the time, like
*someString = "whatever";
someString->assign("whatever");
*someString += 'a';
Application is multithreaded and there's a really nasty glitch. At some point, application crashes. Debugger shows that variable someString has A BAD POINTER. And I have no idea how this is possible
delete someString;
IS NEVER CALLED.
I've looked to all the references of that string pointer and here's what I can tell you:
delete on that pointer is never called.
that pointer is never assigned to anything else (where it may be deleted later).
pointer value of that string is never altered in any way (debugger shows 'Bad Ptr').
other class variables seem fine like they are supposed to be.
Therefore, I need to find a way to check when a destructor is called on a specific object. In fact, array of objects.
So, is there a way to set a breakpoint on a destructor (or any other method) on a specific set of objects (I'm working on visual studio 2010 proffessional)?
If you are multithreading, consider implementing a locking mechanism ... (if you didn't do it already) for your string member. Highly possible one thread tries to write to a pointer which is being reallocated in a different thread... or something like this. A little bit more code would help us to understand the problem in a deeper context.