代码:
int *ptr = new int[10];
int *q = ptr;
delete q;
Run Code Online (Sandbox Code Playgroud)
工作正常没有任何问题(没有运行时错误).
但是,以下代码:
int *ptr = new int[10];
int *q = ptr;
q++;
delete q;
Run Code Online (Sandbox Code Playgroud)
导致运行时错误.
我使用Microsoft Visual Studio-8和Win-7作为平台.
我无法弄清楚为什么在第二种情况下会出现运行时错误?
假设我在C++类中有以下构造函数:
MyClass::MyClass()
{
char* buffer = malloc(100);
if (0 != someD3DXCallThatCanFail(..., buffer, ...))
{
free(buffer);
throw MyException(L"some message");
}
char* buffer2 = malloc(200);
if (0 != anotherD3DCallThatCanFail(..., buffer2, ...))
{
free(buffer);
free(buffer2);
throw MyException(L"another message");
}
.. more code here where buffer and buffer2 are still used
free(buffer);
free(buffer2);
}
Run Code Online (Sandbox Code Playgroud)
编辑:我讨厌malloc/free和new/delete,但不幸的是我需要使用缓冲区来加载纹理,然后将纹理传递给ID3D10ShaderResourceView,ID3D10Buffer,顶点缓冲区等.所有这些都需要指向缓冲区的指针.
我试图使用异常而不是返回错误代码.我还希望在需要它们的地方创建缓冲区,并在不再需要它们之后立即释放它们.
然而,看起来很难看的是,如果出现错误,无论我是否返回错误代码或抛出异常,我仍然应该记得清理到那时为止创建的任何缓冲区.如果我有10个缓冲区和10个可能的错误点,我将不得不调用free()100次(在每个错误情况下记得释放每个缓冲区).
现在假设我或者更糟糕的是,我的同事想要改变一些逻辑,比如在中间的某个地方添加另一个缓冲区.现在,他必须通过方法的其余部分查看可能发生的所有错误,并在每个这样的位置为该缓冲区添加free().如果他赶时间,他可以很容易地忽略一些这样的地方,并且你有内存泄漏.
这也极大地淹没了代码.
finally关键字可以解决Java或C#中的问题.无论代码在哪里发生异常,我仍然会在"finally"中清理所有缓冲区(顺便说一句,你不需要使用垃圾收集).在我理解的C++中,我可能必须为任何这样的缓冲区创建一个成员变量,并在析构函数中确保清理缓冲区.看起来对我来说也很难看,因为名为"pBuffer"的成员变量,即使是私有变量,也只是垃圾,因为它只在一个方法中使用(在本例中是构造函数),并且其余部分始终为NULL.时间.
必须是一个常见问题,但我没有设法使用搜索找到答案.谢谢!
我在代码中使用了额外的括号.我想当在局部变量作用域结束后应该调用析构函数但它不能像这样工作:
class TestClass {
public:
TestClass() {
printf( "TestClass()\n" );
}
~TestClass() {
printf( "~TestClass()\n" );
}
};
int main() {
int a, b, c;
{
TestClass *test = new TestClass();
}
}
Run Code Online (Sandbox Code Playgroud)
它输出:
识别TestClass()
所以它不会调用TestClass的析构函数,但为什么呢?如果我手动调用它(删除测试),它会调用析构函数.但是为什么它不会在第一种情况下调用析构函数呢?
我想使用map进行键/成员搜索,问题是该类包含malloc调用分配的缓冲区成员.
struct Key {
int key1;
int key2;
bool operator < (Key & a) { .... }
};
struct Entity {
unsigned char *data;
};
typedef std::map(Key, Entity) TMap;
Run Code Online (Sandbox Code Playgroud)
然后我可以用键插入数据,如:
Tmap map;
Key key;
Entity ent;
ent.data = malloc(size);
key.key1 = xx;
key.key2 = xx;
map.insert( ...(key,ent));
Run Code Online (Sandbox Code Playgroud)
问题是我希望删除地图时自动释放"ent.data"指针.同时,我希望在进行地图查找操作时可以访问"数据"来读取缓冲数据.
我试图将析构函数添加到结构实体,但它似乎导致一些重复的免费问题.
解决方案是什么?
[解决方案]:1.使用shared_ptr:
typedef std::tr1:shared_ptr(unsigned char) CharPtr;
struct Entity {
CharPtr data;
}
ent.data = CharPtr((unsigned char*)malloc(size), free);
Run Code Online (Sandbox Code Playgroud)
或另一种解决方案 使用Vector作为Eugene Homyakov提到.
我有以下方法:
class MyClass
{
public:
MyClass;
bool method (MyClass &obj);
};
void MyClass::method (MyClass &obj)
{
MyClass *c = new MyClass;
try{
//code
//access another method
return true;
}
catch (std::string s)
{
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我应该在哪里删除之前或之前指向c对象的指针 ?MyClass:return truereturn false
好吧,所以我最近深入研究了C++并且我已经把所有东西都搞砸了.指针最终开始有意义,直到我应该使用它们,如何正确实现它们等.
然而,有一个关于指针的基本用法的一个小问题,我仍然需要回答.我会直接跳到代码:
具有以下类别A和功能foo(A* bar)......
class A
{}
void foo(A* bar)
{}
Run Code Online (Sandbox Code Playgroud)
......以下电话之间有什么区别foo?
A* a;
A b;
foo(a);
foo(&b);
Run Code Online (Sandbox Code Playgroud)
他们都编译得很好,据我所知,我没有遇到任何问题.
我认为那A b;是在那里实例化的,而A* a;需要创建new(因为它实际上没有创建对象,它只是对潜在A对象进行了4字节的长引用).
我可以,如果我正确地考虑这个,做a = b;(编辑制作a = &b),然后成功传递a给foo.但是,如果我不这样做a = &b并foo尝试读取指向的(不存在的)对象a,则会导致运行时错误.
此外,如果以上是正确的,那么我认为我可以成功通话foo(&b);.
我对么?
谢谢!
我正在为函数中的数组动态分配内存.我的问题是:一旦函数完成运行就释放了内存?
码:
void f(){
cv::Mat* arr = new cv::Mat[1];
...
}
Run Code Online (Sandbox Code Playgroud) 我没有得到这个,当我调用head->value它时返回我添加到链表的最后一个值.它应该不归还我的第一个项目,因为head它只在空的时候设置吗?正确?我想也许代码中还有其他一些错误.
void LinkedListPQueue::enqueue(const string& elem) {
cell *newCell = new cell;
newCell->value = elem;
newCell->next = NULL;
if(this->isEmpty()) {
this->head = this->tail = newCell;
} else {
// find smallest and put it there
this->tail->next = newCell;
this->tail = newCell;
}
}
Run Code Online (Sandbox Code Playgroud)
在标题中声明
struct cell {
std::string value;
cell *next;
};
cell *head, *tail;
Run Code Online (Sandbox Code Playgroud) 我刚从Java切换到C ++,到目前为止一切进展顺利。语言有点难,但是我感觉好像正在流行。不过,我有一个关于析构函数的问题,为此,我将提供我当前的代码,希望有人可以对我应该做什么和如何进行澄清。
我正在用OpenGL编写游戏,并创建了三个类:Vector3D,Dimension3D和Cuboid。我的问题是这样开始的,我的长方体有一个Vector3D和Dimension3D的实例,您将很快看到它们。我需要知道将Cuboid类标记为删除后如何处理(确切的例程)。或更准确地说,如果我需要在发生此类事件时显式销毁Vector3D和Dimension3D实例。我希望我足够清楚地阐明这个问题。
这是我的课。
(Vector3D.cpp)
#include "Vector3D.h"
Vector3D::Vector3D(){
}
Vector3D::Vector3D( const float& x , const float& y , const float& z ){
this->x = x;
this->y = y;
this->z = z;
}
Vector3D::~Vector3D(){
}
void Vector3D::setX( const float& x ){
this->x = x;
}
void Vector3D::setY( const float& y ){
this->y = y;
}
void Vector3D::setZ( const float& z ){
this->z = z;
}
float Vector3D::getX(){
return x;
}
float Vector3D::getY(){
return y;
}
float Vector3D::getZ(){
return z;
}
Run Code Online (Sandbox Code Playgroud)
(Vector3D.h) …
我是 C++ 新手,想知道什么时候应该使用 new,什么时候不应该使用,例如“int x = 5”或“int * x = new int(5)”。我知道新在堆中保留内存,因此在块结束时不会被删除,但由于保存地址的变量将在块之外变得不可访问,我看不到任何好处。
例子:
if(x) {
int * z = new int(5);
// Do something
}
// At this point the 5 is saved somewhere but since z is unaccessible I can't use it.
Run Code Online (Sandbox Code Playgroud)
补充:这个问题没有重复,因为其他问题只解释了什么是堆,而没有描述它的好处。
可能重复:
删除NULL指针是否安全?
在我的头文件中,我声明了一个类范围内的变量:
FaultModel<double> *fm_req_set_odom_px;
Run Code Online (Sandbox Code Playgroud)
...在类构造函数中有条件地初始化,具体取决于配置文件的值:
const char *configModel = ConfigReader->ReadString("FaultModel");
if (strcmp(configModel, "cyclic") == 0)
fm_req_set_odom_px = new CyclicFaultModel<double>();
Run Code Online (Sandbox Code Playgroud)
我的问题是:我是否需要用条件包装删除来检查模型是否已初始化,或者在任何一种情况下都可以安全删除它?
if (fm_req_set_odom_px != NULL) // Is this necessary?
delete fm_req_set_odom_px;
Run Code Online (Sandbox Code Playgroud) 我读pointer作为点缀C,使得C一种特殊的语言.但是,我也使用C++中的指针.我猜在C++中使用指针比在C中使用指针有一些限制.因为指针是C的数据类型.如果我被要求编写一个纯粹的程序C++,我可以使用指针吗?
在我的C++类中,我需要分配一个带指针和/或引用的方法.所以我做了这个棘手的事情:
(假设aclass是一个类变量AnotherClass*)
void MyClass::setElem(AnotherClass *pVal)
{
aclass = pVal;
}
void MyClass::setElem(AnotherClass &refVal)
{
aClass = &article;
}
Run Code Online (Sandbox Code Playgroud)
但在我看来,听起来并不那么"优雅"......
更好的方法来实现这一目标