在不同的编译器版本中调用new[]和delete[]
Calling new [] and delete [] in different compiler versions
为了实现一个只在旧编译器版本下运行的框架,我不得不为我的动态链接库设计一个接口,该接口可以在不同的编译器版本中工作。我想出了一个返回字符串的代码:
char * returnCharStr() {
...
auto ret = new char[ str.length ];
... // copy string data into ret
return ret;
}
现在,为了避免内存泄漏,我必须在某个时刻(在另一个编译器版本编译的代码中)对返回的字符串调用delete []
:
...
auto cstr = returnString();
... // work with cstr
delete [] cstr;
此代码在运行时崩溃。解决方案是在编译到动态库(returnCharStr()
函数所在的库)中的函数内部调用delete []
。问题是,为什么代码在delete []
语句上崩溃?
用一个框架分配的内存必须由同一个框架释放,尤其是当内存在不同的环境、不同的编译器等之间传递时。您无法控制调用方对内存的处理,调用方也不知道内存是如何分配的,因此无法直接释放内存。
要做你正在尝试的事情,你必须暴露另一个函数来正确释放内存,例如:
char * returnCharStr() {
...
char* ret = new char[ str.length ];
// copy string data into ret...
return ret;
}
void freeCharStr(char *str) {
delete[] str;
}
char* cstr = returnString();
// work with cstr...
freeCharStr(cstr);
我在不同版本的编译器之间没有遇到过这样的问题,因为内存的分配方式并没有随着时间的推移而发生太大变化。
然而,有些编译标志彼此之间肯定不兼容,例如/MT
和/MTd
。它们使用不同类型的分配器和解除分配器(调试版本添加填充缓冲区来检查是否存在"简单"缓冲区溢出,并在检测到这种情况时生成错误)
如果你不知道现有的二进制文件是如何编译的,那么很难猜测,尽管我认为有一种方法可以查看二进制文件,但我真的不知道该查看什么。不过,这可能是另一个stackoverflow问题的主题。
如果您可以控制两个二进制文件的编译,那么只需确保使用相同的标志即可。如果你不在新的二进制文件中全部尝试,看看哪一个有效。。。我想它将是一个没有d
(调试)的,所以你可能必须在多线程打开或不打开的情况下进行测试
相关文章:
- new[] / delete[] 并在C++中抛出构造函数/析构函数
- QQuickView new-delete-type-mismatch
- 创建 myNew/myDelete 以替换 new/new[]/delete/delete[]
- 为多线程环境包装 c++ new/delete 的安全/好方法
- c++ 运算符 new[]/delete [] 是否调用运算符 new/delete?
- C++内存分配失败(使用 new & delete)
- c++重载运算符new delete
- 在 C++ 中将 malloc/free 替换为 new/delete
- new/delete 和 ::new/::d elete 有什么区别?
- 我什么时候应该在C++中重载new/delete
- 在C++中,"new/delete"在结构上代替"malloc/free"有多好?
- 为什么我的信号槽比QThreadPool+new+delete慢
- malloc()/free()/new/delete/delete[] 的算法复杂度是多少?
- C++中new[]/delete[]与new/delete之间的差异
- 标准C++的哪些部分将调用malloc/free而不是new/delete
- C++中的 malloc/free 和 new/delete 兼容性
- 编译器将 malloc/free 或 new/delete 对优化为 alloca
- 在 ANSI C 中使用 new/delete 的缺点
- 为什么使用 malloc/free,当我们有 new/delete 时
- c++如何知道在new/delete之后指向内存的位置