I'm using a std::shared_ptr<std::map<std::string,std::string> > ptr and I'd like to insert into the map using the more familiar map[key] = value; approach instead of using ptr->insert(std::map<std::string,std::string>::value_type("blah","blahh"));. When I try ptr["blah"] = "blahh"; or (*ptr)["blah"] = "blahh"; the compiler throws a fit. Does anyone know how to do this? I'm fairly new to smart pointer so forgive me if this is a ridiculous question.
Related
I've been looking into smart pointers, unit testing how they manage memory and am finding and unexpected issue that all the examples recommend doing, but it creates a huge memory leak for me.
This seems to occur when I use a class that has a constructor that builds from another copy of the same class. I'll give an example.
If I have a class like:
Class foo{
public:
//Ignore unsafe practices here
HeavyInMemory* variable;
foo(){
variable = new HeavyInMemory();
}
foo(foo* copyThis){
variable = nullptr;
if(copyThis){
variable = new HeavyInMemory(copyThis->variable);
}
}
~foo(){
delete variable;
}
}
I find that I will get a huge memory leak because std::make_shared has no way to tell the difference between make_shared(args) and make_shared(new T)
Main(){
for(int i =0; i < 100; i++{
//Should not leak, if I follow examples of how to use make_shared
auto test = make_shared<foo>(new foo());
}
//Checking memory addresses these do not match, checking total program memory use, leaks like a
//sieve.
}
Am I misunderstanding something?
Do the examples just not consider this as most use primitive types as examples rather than classes.
Does c++11 just not support the make_shared(new T) format even though I see old books like scott meyers books from 1992. It just doesn't make sense.
Also why would you use make_shared(new T) over make_shared(args)? I've seen a couple threads where people have asked this on here, but neither seemed to actually answer the question with a code example.
//As they mainly say code compiler order causes the leak but in my example this would still leak:
auto originalObject = new foo();
auto expectedDestructorWhenOutofScope = make_shared<foo>(originalObject);
//I have found if I give if the object instead it doesn't leak, but this is getting into the realms of
//hacks that may sometimes work
auto originalObject = new foo();
auto expectedDestructorWhenOutofScope = make_shared<foo>(*originalObject);
EDIT:
Thanks to Igor Tandetnik I now see I am using make_shared entirely wrong. It should be used as a constructor. Thanks again Igor I appreciate it.
//Create new
auto expectedDestructorWhenOutofScope = make_shared<foo>();
//Use object already created
std::shared_ptr<Object> p2(new foo())
I'm trying to figure out how to implement this ObjC code in swift:
const unsigned char information[] = {0x95, 0x5f, 0x2e};
I have trying doing this: let information = [0x95, 0x5f, 0x2e] but when I use break points and debug the program it says that the array information has no values in it. Would someone be able to help me figure this out?
Thank you!
Jeff is correct.
You cannot use the information[] syntax anymore.
arrayName:[Type] = [member1, member2, etc]
is the correct way to initialize an array.
Actually, to be more complete with this answer:
internal let arrayName:[Type] = [member1, member2, etc]
if you will not be modifying the array.
internal var arrayName:[Type] = [member1, member2, etc]
if you will be modifying the array later.
I understand that internal is the default access, but I'm finding with Swift that I need to be careful about how Swift infers types; I now always specify a type in a variable declaration and this care just carries over to explicitly declaring the access.
let information: [CUnsignedChar] = [0x95, 0x5f, 0x2e]
println(information) // output [149, 95, 46]
I'm pretty new to C++ and have run into a problem which I have not been able to solve. I'm trying to convert a System::String to a wchar_t pointer that I can keep for longer than the scope of the function. Once I'm finished with it, I want to clean it up properly. Here is my code:
static wchar_t* g_msg;
void TestConvert()
{
pin_ptr<const wchar_t> wchptr = PtrToStringChars("Test");
g_msg = (wchar_t*)realloc(g_msg, wcslen(wchptr) + 1);
wcscpy(g_msg, wchptr);
free (g_msg); // Will be called from a different method
}
When the free is called, I'm getting "HEAP CORRUPTION DETECTED: after Normal block (#137) at 0x02198F90."
Why would I be getting this error?
Andrew L
I think the you're allocating too small memory block for the string. Each character takes 2 bytes (in MSVC) because it's a wide string:
g_msg = (wchar_t*)realloc(g_msg, (wcslen(wchptr) + 1)*sizeof(wchar_t));
System::String is a managed string class, not a C++ string class. You need to convert to a std::wstring, which manages it's own memory, not a const wchar_t*.
I'm building a compiler with reflection.emit in my spare time, and i've come to a problem that i'm not understanding.
A little context, I've a runtime with a couple of types and one of them is Float2, a simpler vector struct with two float values (X and Y). I've made a couple of properties that allow me to swizzle the values (a la hlsl). For example if i have a new Float2(1.0f, 2.0f), if i make something like (new Float2(1.0f, 2.0f)).YX i'm going to get a Float2(2.0f, 1.0f)
I'm using this type in my language and currently testing this case (minor details of the language omitted):
float2 a = float2(1.0, 2.0).yx;
return a;
I'm transforming float2(1.0, 2.0) in a new call and accessing the property YX of my Float2 type in .yx.
The problem is I'm getting a "System.AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.". I don't understand why because if I make something like this:
float2 a = float2(1.0, 2.0);
return a;
Everything goes well.
The IL code that i'm generating is the following (I think the problem occurs in "L_0014: stloc.0", I don't know why it happens though) :
.method public virtual final instance valuetype
[Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 Main() cil managed
{
.maxstack 3
.locals init (
[0] valuetype [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 num)
L_0000: ldc.r4 1
L_0005: ldc.r4 2
L_000a: newobj instance void [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2::.ctor(float32, float32)
L_000f: call instance valuetype [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2 [Bifrost.Psl]Bifrost.Psl.Compiler.Runtime.Float2::get_XY()
L_0014: stloc.0
L_0015: ldloc.0
L_0016: ret
}
Result of peverify:
[IL]: Error: [offset 0x0000000F]
[found value 'Bifrost.Psl.Compiler.Runtime.Float2'][expected address of value 'Bifrost.Psl.Compiler.Runtime.Float2'] Unexpected type on the stack.
The IL looks OK, although I don't know what your Float2 looks like.
I found the best way to debug this is to save the assembly to disk, then run peverify. Any code that generates an AccessViolationException will cause an error in peverify.
Edit: The newobj doc on MSDN talks about pushing an object reference onto the stack, which I took to be a pointer to a value type. If you're getting this error from peverify then I think you need to
newobj
stloc to a temporary variable
ldloca to get the address of the value type stored in the temporary variable
call
Now that I think about it, this is what the C# compiler does if you do a direct call on a value type like 4.ToString();.
When I use a GUI in C++ the text fields are stored as managed strings, i think. I need a way to convert them to standard ints, floats and strings. Any help?
You can convert a System.String into an unmanaged char * using Marshal.StringToHGlobalAnsi. Make sure you free it when you're done by calling Marshal.FreeHGlobal. To convert the strings to numeric values, you can use the regular .NET parsing functions such as Int32.Parse.
To use managed memory in native code, you must copy the contents of the managed memory into native memory first.
So for example:
Copying the contents from managed memory is as follows:
const int len = 50;
BYTE *destination = new BYTE[nLength];
System::Byte source[] = new System::Byte[len];
System::Runtime::InteropServices::Marshal::
Copy(source, 0, IntPtr((void *)destination, len);
Because we are dealing with managed memory, garbage collection can shift and move the managed data to another location and all would be lost if we tried to locate the data we want to convert.
Therefore we want to "pin it in memory" by using __pin to convert from managed to unmanaged:
const int len = 50;
BYTE *source = new BYTE[len];
System::Byte destination[] = new System::Byte[len];
BYTE __pin *managedData = &(destination[0]);
::memcpy(source, managedData, len);
You can simply convert System::String^ objects to MFC CString by
CString* name = new CString(managedName);
where managedName is a managed String.