为什么C ++程序员最小化使用“新”? [英] Why should C++ programmers minimize use of 'new'?
问题描述
我偶然发现Stack Overflow问题使用std :: list时,内存泄漏与std :: string< std :: string> 和其中一条评论说:
< blockquote>
停止使用 new
这么多。我看不到任何原因你使用新的任何地方
你做了。你可以通过C ++中的值创建对象,它是
中使用语言的巨大优势之一。你不必在heap *上分配
的一切。停止像一个Java程序员一样思考。
*在引文中修正错误的堆栈 > 我不知道他的意思。为什么应该使用C ++中的值尽可能多地创建对象,它在内部有什么区别? 有两种广泛使用的内存分配技术:自动分配和动态分配。通常,每个堆栈和堆都有一个相应的内存区域。 堆栈总是以顺序方式分配内存。它可以这样做,因为它要求您以相反的顺序释放内存(先进先出,FILO)。这是用于许多编程语言中的局部变量的存储器分配技术。 在C ++中,这被称为自动存储因为存储在范围结束时自动声明。一旦执行当前代码块(使用 堆允许更灵活的内存分配模式。记账更复杂,分配更慢。因为没有隐式释放点,您必须手动释放内存,使用 即使使用堆较慢,并且可能导致内存泄漏或内存碎片,动态分配也有很好的用例,因为它的限制较少。 使用动态分配的关键原因: 您不知道编译时需要多少内存。例如,当将文本文件读入字符串时,通常不知道文件具有什么大小,因此您无法确定在运行程序之前要分配多少内存。 您想要分配内存,在离开当前块后会持续存储。例如,你可能需要写一个返回文件内容的函数 在C ++中有一个简洁的结构,称为 destructor 。此机制允许您通过将资源的生命周期与变量的生存期对齐来管理资源。此技术称为 RAII ,是C ++的区别点。它将资源包装到对象中。 实际上分配了可变的内存量。 在此代码片段中: 有不必要的动态内存分配。该程序需要更多的打字(!),并引入忘记释放内存的风险。 基本上,最后一段总结起来。尽可能频繁使用自动存储功能可以让您的程序: 在引用的问题中,还有其他问题。特别是下面的类: 实际上使用比下面更危险: 原因是 使用原始版本,此程序可能会崩溃,因为它使用 广泛使用 RAII 被认为是C ++的最佳实践,因为上述所有原因。然而,还有一个额外的好处,并不是立即显而易见的。基本上,它比它的部分的总和更好。整个机制组成。 如果您使用 然后 分配四个 I stumbled upon Stack Overflow question Memory leak with std::string when using std::list<std::string>, and one of the comments says this: Stop using *Fixed misspoken "stack" in the citation. I'm not really sure what he means by that. Why should objects be created by value in C++ as often as possible, and what difference does it make internally? Did I misinterpret the answer? There are two widely-used memory allocation techniques: automatic allocation and dynamic allocation. Commonly, there is a corresponding region of memory for each: the stack and the heap. The stack always allocates memory in a sequential fashion. It can do so because it requires you to release the memory in the reverse order (First-In, Last-Out: FILO). This is the memory allocation technique for local variables in many programming languages. It is very, very fast because it requires minimal bookkeeping and the next address to allocate is implicit. In C++, this is called automatic storage because the storage is claimed automatically at the end of scope. As soon as execution of current code block (delimited using The heap allows for a more flexible memory allocation mode. Bookkeeping is more complex and allocation is slower. Because there is no implicit release point, you must release the memory manually, using Even if using the heap is slower and potentially leads to memory leaks or memory fragmentation, there are perfectly good use cases for dynamic allocation, as it's less limited. Two key reasons to use dynamic allocation: You don't know how much memory you need at compile time. For instance, when reading a text file into a string, you usually don't know what size the file has, so you can't decide how much memory to allocate until you run the program. You want to allocate memory which will persist after leaving the current block. For instance, you may want to write a function In C++ there's a neat construct called a destructor. This mechanism allows you to manage resources by aligning the lifetime of the resource with the lifetime of a variable. This technique is called RAII and is the distinguishing point of C++. It "wraps" resources into objects. actually allocates a variable amount of memory. The In particular, it implies that in this snippet: there is unneeded dynamic memory allocation. The program requires more typing (!) and introduces the risk of forgetting to deallocate the memory. It does this with no apparent benefit. Basically, the last paragraph sums it up. Using automatic storage as often as possible makes your programs: In the referenced question, there are additional concerns. In particular, the following class: Is actually a lot more risky to use than the following one: The reason is that Using the original version, this program will likely crash, as it uses Extensive use of RAII is considered a best practice in C++ because of all the reasons above. However, there is an additional benefit which is not immediately obvious. Basically, it's better than the sum of its parts. The whole mechanism composes. It scales. If you use the Then allocates four 这篇关于为什么C ++程序员最小化使用“新”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
堆栈
{}
定界)完成,则会自动收集该块中所有变量的内存。这也是调用清除资源的时刻。
堆
delete
或 delete []
c $ c>免费)。
使用动态分配的原因
string readfile(string path)
。在这种情况下,即使堆栈可以保存整个文件内容,也不能从函数返回并保留分配的内存块。
为什么动态分配通常是不必要的
std :: string
是一个完美的例子。此片段:
int main(int argc,char * argv [])
{
std: :string program(argv [0]);
}
std :: string
对象使用堆分配内存,并在其析构函数中释放它。在这种情况下,您不需要手动管理任何资源,仍然能够获得动态内存分配的好处。
int main(int argc,char * argv [])
{
std :: string * program = new std :: string(argv [0]); //坏了!
delete程序;
}
为什么你应该尽可能经常使用自动存储
奖励积分
class Line {
public:
Line
〜Line();
std :: string * mString;
};
Line :: Line(){
mString = new std :: string(foo_bar);
}
Line ::〜Line(){
delete mString;
}
class Line {
public:
Line();
std :: string mString;
};
Line :: Line(){
mString =foo_bar;
//注意:有一个更清洁的方式来写这个。
}
std :: string
正确定义了一个复制构造函数。考虑以下程序:
int main()
{
Line l1;
Line l2 = l1;
}
delete
两次。使用修改后的版本,每个 Line
实例将拥有自己的字符串 instance ,每个都有自己的内存,
Line
类作为构建块:
class Table
{
线边框[4];
};
int main()
{
表table;
}
std :: string
实例,四个行
实例,一个表
实例和所有字符串的内容和自动。
new
so much. I can't see any reason you used new anywhere
you did. You can create objects by value in C++ and it's one of the
huge advantages to using the language. You do not have to allocate
everything on the heap*. Stop thinking like a Java programmer.Stack
{}
) is completed, memory for all variables in that block is automatically collected. This is also the moment where destructors are invoked to clean up resources.Heap
delete
or delete[]
(free
in C). However, the absence of an implicit release point is the key to the heap's flexibility.Reasons to use dynamic allocation
string readfile(string path)
that returns the contents of a file. In this case, even if the stack could hold the entire file contents, you could not return from a function and keep the allocated memory block.Why dynamic allocation is often unnecessary
std::string
is a perfect example. This snippet:int main ( int argc, char* argv[] )
{
std::string program(argv[0]);
}
std::string
object allocates memory using the heap and releases it in its destructor. In this case, you did not need to manually manage any resources and still got the benefits of dynamic memory allocation.int main ( int argc, char* argv[] )
{
std::string * program = new std::string(argv[0]); // Bad!
delete program;
}
Why you should use automatic storage as often as possible
Bonus points
class Line {
public:
Line();
~Line();
std::string* mString;
};
Line::Line() {
mString = new std::string("foo_bar");
}
Line::~Line() {
delete mString;
}
class Line {
public:
Line();
std::string mString;
};
Line::Line() {
mString = "foo_bar";
// note: there is a cleaner way to write this.
}
std::string
properly defines a copy constructor. Consider the following program:int main ()
{
Line l1;
Line l2 = l1;
}
delete
on the same string twice. Using the modified version, each Line
instance will own its own string instance, each with its own memory and both will be released at the end of the program.Other notes
Line
class as a building block: class Table
{
Line borders[4];
};
int main ()
{
Table table;
}
std::string
instances, four Line
instances, one Table
instance and all the string's contents and everything is freed automagically.