473,624 Members | 2,478 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Returning local variables from DLL

Hi together,

I am a bit clueless about the following problem:

In the following code excerpt

std::string getStr()
{

std::string bla="asdfsa";
return bla;
}

void func1()
{

{
std::string str1=getStr();
}
return;
}

str1 is destroyed when the scope inside func1() is left.
Works fine.
But, if getStr() is inside a DLL and is called from func1() in a main
program, this does not work.
At least, I experience that in my code.
Actually, the getStr() is a member function of a class in the DLL which
is exported.
Are they not sharing the same memspace?
Am I missing something?

See callstack below

NTDLL! 7c911230()
NTDLL! 7c97cd80()
NTDLL! 7c970af8()
KERNEL32! 7c85e9cf()
_CrtIsValidHeap Pointer(const void * 0x009d33d8) line 1697
_free_dbg_lk(vo id * 0x009d33d8, int 0x00000001) line 1044 + 9 bytes
_free_dbg(void * 0x009d33d8, int 0x00000001) line 1001 + 13 bytes
free(void * 0x009d33d8) line 956 + 11 bytes
operator delete(void * 0x009d33d8) line 7 + 10 bytes
std::allocator< char>::dealloca te(void * 0x009d33d8, unsigned int
0x00000021) line 64 + 16 bytes
std::basic_stri ng<char,std::ch ar_traits<char> ,std::allocator <char>
>::_Tidy(unsign ed char 0x01) line 592
std::basic_stri ng<char,std::ch ar_traits<char> ,std::allocator <char>
>::~basic_strin g<char,std::cha r_traits<char>, std::allocator< char() line 59 + 17 bytes

Thanks in advance,

--
Regards,

Rainer

Dec 14 '06 #1
6 1856
* RT*****@web.de:
<off-topic>
See the FAQ for information about relevant newsgroups.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Dec 14 '06 #2
<RT*****@web.de wrote in message
news:11******** **************@ l12g2000cwl.goo glegroups.com.. .
Hi together,

I am a bit clueless about the following problem:

In the following code excerpt

std::string getStr()
{

std::string bla="asdfsa";
return bla;
}

void func1()
{

{
std::string str1=getStr();
}
return;
}

str1 is destroyed when the scope inside func1() is left.
Works fine.
But, if getStr() is inside a DLL and is called from func1() in a main
program, this does not work.
At least, I experience that in my code.
Actually, the getStr() is a member function of a class in the DLL which
is exported.
Are they not sharing the same memspace?
Am I missing something?

See callstack below

NTDLL! 7c911230()
NTDLL! 7c97cd80()
NTDLL! 7c970af8()
KERNEL32! 7c85e9cf()
_CrtIsValidHeap Pointer(const void * 0x009d33d8) line 1697
_free_dbg_lk(vo id * 0x009d33d8, int 0x00000001) line 1044 + 9 bytes
_free_dbg(void * 0x009d33d8, int 0x00000001) line 1001 + 13 bytes
free(void * 0x009d33d8) line 956 + 11 bytes
operator delete(void * 0x009d33d8) line 7 + 10 bytes
std::allocator< char>::dealloca te(void * 0x009d33d8, unsigned int
0x00000021) line 64 + 16 bytes
std::basic_stri ng<char,std::ch ar_traits<char> ,std::allocator <char>
>>::_Tidy(unsig ned char 0x01) line 592
std::basic_stri ng<char,std::ch ar_traits<char> ,std::allocator <char>
>>::~basic_stri ng<char,std::ch ar_traits<char> ,std::allocator <char() line
59 + 17 bytes


Thanks in advance,
DLLs have nothing to do with C++, that's part of the OS and specific
compiler. Try a microsoft newsgroup such as
comp.os.ms-windows-programmer.win3 2
or others.
Dec 14 '06 #3
On Dec 14, 11:56 am, "RTha...@web.de " <RTha...@web.de wrote:
Hi together,

I am a bit clueless about the following problem:

In the following code excerpt

std::string getStr()
{

std::string bla="asdfsa";
return bla;

}void func1()
{

{
std::string str1=getStr();
}
return;

}str1 is destroyed when the scope inside func1() is left.
Works fine.
But, if getStr() is inside a DLL and is called from func1() in a main
program, this does not work.
At least, I experience that in my code.
Actually, the getStr() is a member function of a class in the DLL which
is exported.
Are they not sharing the same memspace?
Am I missing something?
Contrary to the previous replies to your post, there is something in
this for the comp.lang.c++ community. We encountered a problem
previously which looks very similar to the above problem, and as it
turned out it had a substantial influence on our software design.

In our case, we got a similar message when we unknowingly built our
application (multiple shared libraries/DLL's and some main stubs which
used them) in such a way that each DLL had its own memory heap. We
thought we were using default compiler flags, but as it turned out, we
were not for a DLL arrangement. Under Windows using VC++ (I forget the
version), we got the above behavior, but under linux we had no problems
at all. We temporarily resolved the problem by using appropriate
compiler flags until we found a more robust design solution.

Where this is relevant to the comp.lang.c++ community is that the C++
standard says nothing at all about shared libraries. It talks about
"translatio n units", but that's a different (but related) thing and
doesn't address situations like the above. Indeed, since it does not
prohibit separate memory heaps in DLL's, there's a fair argument which
says it is okay for the compiler implementor to do that. Unfortunately,
this is often not what the programmer expects and can lead to problems
like the one you posted.

There are a few good items in "C++ Coding Standards" by Herb Sutter and
Andrei Alexandrescu which talk about these things (see the "Namespaces
and Modules" section). Item 63 "Use sufficiently portable types in a
module's interface" is particularly relevant, where they discuss
std::string as a function parameter in the module's interface. That
example talks about compiler flags, but the hidden part of std::string
which makes it particularly nasty is that it involves dynamic memory
allocation under the covers. When you force the internal data buffer to
be resized (eg you add characters to the string), memory is allocated
in the module in which that usage of std::string occurred. If you then
pass that string to a different module and it tries to modify it, then
the other module will first try to deallocate the internal buffer and
BAM! there goes your program if your modules are using their own
private memory heaps. If you are returning a std::string by value, then
you essentially have the same problem merely as a result of the
function call mechanics. Which module allocates and deallocates the
memory on each side of the final assignment when the function returns?
Note that all the containers in the STL are vulnerable to this same
gotcha.

If you have to keep the memory heaps separate for some reason (unlikely
from what I can tell from your original post), then there is possibly
still a workaround. You could wrap std::string and make the memory
(re)allocation happen inside your wrapped implementation. Using the
pImpl idiom will suffice to hide this from your compiler so that it
doesn't inline the memory (re)allocation. There is, of course, a
performance penalty for doing this though, so consider carefully if
this matters to you. You should note that this still relies on you
using the same compiler settings and compiler version for all modules
that are going to use your wrapper if you want to have maximum chance
of avoiding inter-module problems (see the book - it contains good
advice on this area).

Hope that helps.

--
Computational Fluid Dynamics, CSIRO (CMIS)
Melbourne, Australia

Dec 14 '06 #4

"RT*****@we b.de дµÀ£º
"
Hi together,

I am a bit clueless about the following problem:

In the following code excerpt

std::string getStr()
{

std::string bla="asdfsa";
return bla;
}

void func1()
{

{
std::string str1=getStr();
}
return;
}
The code is fine.You can prove it by put getStr into yourself's CPP.

Dec 14 '06 #5
On Dec 14, 11:56 am, "RTha...@web.de " <RTha...@web.de wrote:
Hi together,

I am a bit clueless about the following problem:

In the following code excerpt

std::string getStr()
{

std::string bla="asdfsa";
return bla;

}void func1()
{

{
std::string str1=getStr();
}
return;

}str1 is destroyed when the scope inside func1() is left.
Works fine.
But, if getStr() is inside a DLL and is called from func1() in a main
program, this does not work.
At least, I experience that in my code.
Actually, the getStr() is a member function of a class in the DLL which
is exported.
Are they not sharing the same memspace?
Am I missing something?

Contrary to the previous replies to your post, there is something in
this for the comp.lang.c++ community. We encountered a problem
previously which looks very similar to the above problem, and as it
turned out it had a substantial influence on our software design.

In our case, we got a similar message when we unknowingly built our
application (multiple shared libraries/DLL's and some main stubs which
used them) in such a way that each DLL had its own memory heap. We
thought we were using default compiler flags, but as it turned out, we
were not for a DLL arrangement. Under Windows using VC++ (I forget the
version), we got the above behavior, but under linux we had no problems
at all. We temporarily resolved the problem by using appropriate
compiler flags until we found a more robust design solution.

Where this is relevant to the comp.lang.c++ community is that the C++
standard says nothing at all about shared libraries. It talks about
"translatio n units", but that's a different (but related) thing and
doesn't address situations like the above. Indeed, since it does not
prohibit separate memory heaps in DLL's, there's a fair argument which
says it is okay for the compiler implementor to do that. Unfortunately,
this is often not what the programmer expects and can lead to problems
like the one you posted.

There are a few good items in "C++ Coding Standards" by Herb Sutter and
Andrei Alexandrescu which talk about these things (see the "Namespaces
and Modules" section). Item 63 "Use sufficiently portable types in a
module's interface" is particularly relevant, where they discuss
std::string as a function parameter in the module's interface. That
example talks about compiler flags, but the hidden part of std::string
which makes it particularly nasty is that it involves dynamic memory
allocation under the covers. When you force the internal data buffer to
be resized (eg you add characters to the string), memory is allocated
in the module in which that usage of std::string occurred. If you then
pass that string to a different module and it tries to modify it, then
the other module will first try to deallocate the internal buffer and
BAM! there goes your program if your modules are using their own
private memory heaps. If you are returning a std::string by value, then
you essentially have the same problem merely as a result of the
function call mechanics. Which module allocates and deallocates the
memory on each side of the final assignment when the function returns?
Note that all the containers in the STL are vulnerable to this same
gotcha.

If you have to keep the memory heaps separate for some reason (unlikely
from what I can tell from your original post), then there is possibly
still a workaround. You could wrap std::string and make the memory
(re)allocation happen inside your wrapped implementation. Using the
pImpl idiom will suffice to hide this from your compiler so that it
doesn't inline the memory (re)allocation. There is, of course, a
performance penalty for doing this though, so consider carefully if
this matters to you. You should note that this still relies on you
using the same compiler settings and compiler version for all modules
that are going to use your wrapper if you want to have maximum chance
of avoiding inter-module problems (see the book - it contains good
advice on this area).

Hi Craig,

thanks for your kind response. I thought that this had something to do
with C++. Thanks for having a deeper look inside this than the other
replyers.

I hereby forward this thread to comp.os.ms-windows-programmer.win3 2 to
see if those guys find it appropriate and to know what they think about
it.
I hope I am not making a fault in doing this, but if I do, I'm sure
there's somebody who will teach me good behaviour.

As far as I understand you, even allocating the string in the main
module and passing the pointer to the DLL does not help since a
reallocation (grow, shrink) would cause a crash, right?
Is the underlying memory allocation the same as allocation by new?
new uses the global heap, but as I understand even the global heap is
separated into different memspaces for each module.
Or, to be more concrete, if I allocate an object of a user defined type
with new in the DLL and pass the pointer back to the main module which,
then, deletes the object, would this cause the same behaviour?

--
Regards,

Rainer

Dec 14 '06 #6
As far as I understand you, even allocating the string in the main
module and passing the pointer to the DLL does not help since a
reallocation (grow, shrink) would cause a crash, right?
It *might*, depending on what memory heap management the compiler is
using. You need to check your compiler flags for that.
Is the underlying memory allocation the same as allocation by new?
If that is what the author of your particular STL implementation uses.
The std::string class uses the default allocator<char> , which may or
may not be using the global new operator (I'm not sure if the standard
says anything specific about this particular point). In short, maybe,
so don't depend on it.
new uses the global heap, but as I understand even the global heap is
separated into different memspaces for each module.
Maybe, see earlier comment at the top of this reply.
Or, to be more concrete, if I allocate an object of a user defined type
with new in the DLL and pass the pointer back to the main module which,
then, deletes the object, would this cause the same behaviour?
Yes, this can lead to the same behavior as your first posting. It can
even happen if you are allocating/deallocating built in types, since it
is the actual operator new/delete that is the issue, not the underlying
data type. A data type might implement its own operator new/delete, but
that is a red herring to this issue.

--
Computational Fluid Dynamics, CSIRO (CMIS)
Melbourne, Australia

Dec 15 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
2131
by: Oliver Corona | last post by:
I am wondering if anyone has any insights on the performance benefit (or detriment) of declaring local variables instead of referencing members. Is allocating memory for a new variable more efficient than repeatedly referencing the member in a loop? Maybe using a string isn't the best example, but hopefully you get the idea! * example (referencing member):
8
431
by: pertheli | last post by:
I am in a situation where only "goto" seems to be the answer for my program logic where I have to retry calling some repeated functions. Can anybody help in the usage of goto and its effect in local variables, as shown in the stripped code below void MyClass:Process(){ int iMaxRetry = 100;
5
2412
by: masood.iqbal | last post by:
My simplistic mind tells me that having local variables within looping constructs is a bad idea. The reason is that these variables are created during the beginning of an iteration and deleted at the end of the iteration. Kindly note that I am not talking about dynamically allocating memory within a loop, which is a perfectly valid operation (albeit with a chance of resulting in a memory leak, unless we are careful). The most common...
9
2198
by: Stefan Turalski \(stic\) | last post by:
Hi, I done sth like this: for(int i=0; i<10; i++) {...} and after this local declaration of i variable I try to inicialize int i=0;
1
11248
by: bhavin.vyas | last post by:
Friends, I would just like to know that why SQL Server doen't allow us to define a text data type local variable while creating trigger? I tried creating a text variable in a trigger as a local variable and it raises error. "Implicit conversion from data type text to nvarchar is not allowed. Use the CONVERT function to run this query".
5
2430
by: Michal Kwiatkowski | last post by:
Hi! I'm building a class that most of methods have similar intro, something like this: def method(self): var_one = self.attr_one var_two = self.attr_two.another_attr empty_list =
55
6190
by: Zytan | last post by:
I see that static is more restricted in C# than in C++. It appears usable only on classes and methods, and data members, but cannot be created within a method itself. Surely this is possible in C# in some way? Or maybe no, because it is similar to a global variable (with its scope restricted) which C# is dead against? Zytan
8
1935
by: Samant.Trupti | last post by:
Hi All, I am facing a strange problem.. I am calling a function func2 from func1. Before calling func2 all the local variables in func1 looks fine and has their respective values. When function returns back from func2 to func1 all the local variables in func1 has values 0xfdfdfd. Can somebody please explain me what is happening and what is the solution for this? Thanks
3
4218
by: Rene | last post by:
Could someone tell me why is not possible to have Implicitly typed* field level* variables? For example, why won't the following code compile? class Program { var myString = "abc"; static void Main(string args) { }
0
8233
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8170
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
8334
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8474
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5561
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4078
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2604
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1784
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1482
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.