C++中class对象属性的内存管理
Memory management of class object attributes in C++
如果之前有人问过这个问题,我很抱歉。我搜索了互联网,但找不到任何明确的答案。
这是问题所在:
假设我有一个名为 public class 的对象,它有 2 个属性。一个是 int attr1
,另一个是 char * attr2
。构造函数是(我有一个头文件):
Object::Object(int param1, char * param2)
{
attr1=param1;
attr2 = new char[strlen(param2)+1]; // I understand that by doing this the values are stored in the heap
strcpy(attr2, param2);
}
我明白在 class 对象的析构函数中我需要写 delete [] attr2
.
在另一个文件中,main.cpp我这样创建了一个新对象:
char * name = "Aname";
Object myObject = new Object(3, name);
据我了解,每当使用 new
时,该值都存储在堆中。因此 delete
是必要的,以避免内存泄漏。
在这里,我使用 new
运算符创建了一个对象。因此 myObject 是指向存储在堆中的对象的指针。我将需要这样做:delete myObject
当我不再需要它时。
所以这是我的问题:因为 myObject 指向的对象存储在堆中,这是否意味着它的所有属性都存储在堆中(包括 attr1
,它只是一个 int)?
如果是这样,为什么我也不必释放它(意味着在析构函数中使用运算符 delete
)?
谢谢你的帮助!
注意:英语不是我的母语,如有错误请见谅。
您在第二个示例中显示的代码无法编译,因为
myObject
未声明为指针
在 C++11 及更高版本中,非常量 char*
指针不能指向字符串文字。
所以你需要这个:
Object::Object(int param1, const char * param2)
{
attr1 = param1;
attr2 = new char[strlen(param2)+1];
strcpy(attr2, param2);
}
const char * name = "Aname";
Object * myObject = new Object(3, name); // <-- note the * !
话虽如此,您的其他评论都是正确的。由于myObject
是用new
创建的,它的数据成员驻留在动态内存(即堆)中,你必须调用delete myObject
来使用完后销毁它并释放它的内存。并且由于您是 直接 使用 new[]
为 attr2
分配内存,因此您需要手动调用 delete[] attr2
来释放它。
但是,您并不是直接使用new
为attr1
分配内存,因此您不需要手动调用delete attr1
。 attr1
的内存由编译器管理,当myObject
销毁时会自动释放。
简而言之,当某些东西被 function/operator 显式分配时,它必须用相应的 function/operator 显式释放,例如:
当使用 C++ new
或 new[]
运算符显式分配某些内容时,必须使用 delete
或 delete[]
运算符显式释放它, 分别.
如果使用 C 运行时 (m|c|re)alloc()
函数显式分配某些内容,则必须使用 C 运行时 free()
函数显式释放它。
如果使用 Win32 API (Local|Global)Alloc()
或 (Local|Global)ReAlloc()
函数显式分配某些内容,则必须使用 Win32 API (Local|Global)Free()
函数。
等
如果之前有人问过这个问题,我很抱歉。我搜索了互联网,但找不到任何明确的答案。
这是问题所在:
假设我有一个名为 public class 的对象,它有 2 个属性。一个是 int attr1
,另一个是 char * attr2
。构造函数是(我有一个头文件):
Object::Object(int param1, char * param2)
{
attr1=param1;
attr2 = new char[strlen(param2)+1]; // I understand that by doing this the values are stored in the heap
strcpy(attr2, param2);
}
我明白在 class 对象的析构函数中我需要写 delete [] attr2
.
在另一个文件中,main.cpp我这样创建了一个新对象:
char * name = "Aname";
Object myObject = new Object(3, name);
据我了解,每当使用 new
时,该值都存储在堆中。因此 delete
是必要的,以避免内存泄漏。
在这里,我使用 new
运算符创建了一个对象。因此 myObject 是指向存储在堆中的对象的指针。我将需要这样做:delete myObject
当我不再需要它时。
所以这是我的问题:因为 myObject 指向的对象存储在堆中,这是否意味着它的所有属性都存储在堆中(包括 attr1
,它只是一个 int)?
如果是这样,为什么我也不必释放它(意味着在析构函数中使用运算符 delete
)?
谢谢你的帮助!
注意:英语不是我的母语,如有错误请见谅。
您在第二个示例中显示的代码无法编译,因为
myObject
未声明为指针在 C++11 及更高版本中,非常量
char*
指针不能指向字符串文字。
所以你需要这个:
Object::Object(int param1, const char * param2)
{
attr1 = param1;
attr2 = new char[strlen(param2)+1];
strcpy(attr2, param2);
}
const char * name = "Aname";
Object * myObject = new Object(3, name); // <-- note the * !
话虽如此,您的其他评论都是正确的。由于myObject
是用new
创建的,它的数据成员驻留在动态内存(即堆)中,你必须调用delete myObject
来使用完后销毁它并释放它的内存。并且由于您是 直接 使用 new[]
为 attr2
分配内存,因此您需要手动调用 delete[] attr2
来释放它。
但是,您并不是直接使用new
为attr1
分配内存,因此您不需要手动调用delete attr1
。 attr1
的内存由编译器管理,当myObject
销毁时会自动释放。
简而言之,当某些东西被 function/operator 显式分配时,它必须用相应的 function/operator 显式释放,例如:
当使用 C++
new
或new[]
运算符显式分配某些内容时,必须使用delete
或delete[]
运算符显式释放它, 分别.如果使用 C 运行时
(m|c|re)alloc()
函数显式分配某些内容,则必须使用 C 运行时free()
函数显式释放它。如果使用 Win32 API
(Local|Global)Alloc()
或(Local|Global)ReAlloc()
函数显式分配某些内容,则必须使用 Win32 API(Local|Global)Free()
函数。等