您的位置:首页 > 其它

string浅拷贝及其在dll中运用的注意事项

2012-06-18 18:56 267 查看
1.一个原则:某个模块中分配的空间就应该由它来释放!比如说在dll中分配的空间就应由这个dll来释放,而不应该有main来释放,因为dll中用来分配空间的环境可能和main中用来分配的环境不一样。关于这一点window核心编程中的dll里面进行了讲解,但是说真的我还是不明白为什么会这样。但是要记住这个原则!

2.mian 中的如下语句:

string str1("l10");

string str2("l10value");

pi->addElement(str1, str2 );

//pi是指向dll提供的一个接口的指针。

dll中是如下实现addElement函数的:

bool *****::addElement(/*in*/string elementName,/*in*/string elementValue)

{

//。。省略

return true;//返回时对elementName,elementValue进行析构,这导致释放它们具体字符串的空间,

//但是这些字符串的空间是在main 中分配的,所以出现运行时错误!!!(其实是无效内存访问)

}

3.解决方案:

对于上面这种情况我们只要把dll的改成引用就可以了:如下

bool *****::addElement(/*in*/string &elementName,/*in*/string &elementValue)

{

return true;

}

4.反思:感觉把string用于dll并不是一个好主意。

前言:为什么要用浅拷贝。因为假如字符串空间很到的话,若不用浅拷贝则将非常费时且浪费空间。

1.string作为dll输出接口的方法的输入参数,这时可以作为引用来传递。这种情况下容易解决,如上。

这里是指dll中不会对string作任何改变。

2.dll输出接口的方法返回一个string,也就是字符串空间在dll中分配,让后在main中获得这个stirng,

则以为着在main中释放空间,但由于是浅拷贝,所以将出现错误。

dll中的代码如下:

string ****::getString()

{

string s("abc");

return s;

}

main中的代码如下:

main()

{

//省略。。

string strretdll= pi->getString();//

return 0;//返回师调用string的析构函数,进而释放字符串空间,但由于这个空间不是在main模块中分配

则导致错误。

}

好问题出来了:在getString返回时为什么不会把字符串空间析构掉呢? 事实上string的析构函数要调用一个称为

_Tidy(bool)的函数来处理。注意不同的stl实现如何析构string的具体方式是不一样的。总之经过我观察之后,在getString

返回时并不释放字符串空间,尽管执行了析构函数.我想这一点有点像智能指针。

对于这种情况的解决方法:

a.把空间分配和释放均在main中,但是main并不知道要具体分配多少空间

b.把空间分配和释放均在dll中, 但是如何才能在main中调用dll的方法来要求dll释放空间。

//现在该想到com中IUnknown的重要作用了吧!!!!

3.string作为dll输出接口的方法的输出参数。这种情况同样出现情况2的问题。

4.string作为dll输出接口的方法的输入输出参数。具有输出特性时和情况2相似。

思考:能不能用指向string的指针呢?

不方便!!

最后我下一个结论:在dll中string不能作为输出属性的参数!!

所以,我们只能显式地在dll中定义一个输出函数,用这个输出函数来释放dll分配的空间!!

不过也可以在VC工程中使用PROGECT--->SETTINGS 中,选择 C/C++ CATEGORY 选择 code generation 中 user run-time lib 选择 debug multithreanded ,这样也可以避免string 内存没有释放问题。建议一般不在动态链接库中返回 string
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: