如果“新”的范围不同,则合法性和道德性是不同的。并“删除”
我正在函数内创建一个动态数组。代码(下面发布)运行没有任何问题。我想知道我编写的方法是否正确,或者是否会在将来更复杂的代码中产生问题。我知道我的程序(如下)试图实现的特定任务通过字符串或向量可以更好地实现。但我创建了这个人为的例子来表达我的问题。但是,如果您强烈认为应该避免动态数组,请随时分享您的意见及其理由。
我之前的研究结果:我无法找到关于使用 new [] 创建动态数组并随后在不同范围内删除它们的合法性和道德性的连贯讨论。
感谢您的想法和见解。
我的示例代码如下:
============================
#include<iostream>
#include<string>
#include<cctype>
using namespace std;
void getNonPunct(string _str, char* &_npcarr, int &_npsize);
int main()
{
string input_string;
char* npchar_arr;
int npsize;
cout << "Enter any string: ";
getline(cin, input_string);
getNonPunct(input_string, npchar_arr, npsize);
// Now display non-punctuation characters in the string
cout << "string with non-punctuation characters removed:\n";
for (int n = 0; n <= npsize - 1; n++)
cout << npchar_arr[n];
cout << "\n(" << npsize << ") non-punctuation characters\n";
// Now return the memory allocated with 'new' to heap
delete [] npchar_arr;
// Is it okay to 'delete' npchar_arr eve if it was created in the function
// getNonPunct() ?
return(0);
}
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void getNonPunct(string _str, char* &_npcarr, int &_npsize)
//This void function takes an input array of strings containing arbitrary
//characters and returns a pointer to an array of characters containing only
//the non-punctuation characters in the input string. The number of
//non-punctuation characters are stored in size. Prior to the function call,
//int_arr and size are undefined. After the function call, char_arr points to
//the first location of an array of the non-punctuation character array.
//'size' is equal to the number of non-punctuation characters in the input
//string.
{
// First get the number of non-punctuation characters in the string
int str_len, npcount = 0;
str_len = static_cast<int>( _str.length() );
_npsize = 0;
for (int i = 0; i <= str_len - 1; i++)
{
if ( !ispunct(_str[i]) )
_npsize++;
}
// Now that you know how many non-punctuation characters are in the string,
// create a (dynamic) character array of _npsize.
_npcarr = new char [_npsize];
for (int k = 0; k <= str_len - 1; k++)
{
if ( !ispunct(_str[k]) )
_npcarr[npcount++] = _str[k];
}
return;
}
I am creating a dynamic array inside a function. The code (posted below) runs without any problem. I am wondering if the way I have written is the right way to do it or if it will create problems in more complicated codes in the future. I am aware that the specific task my program (below) is trying to achieve is better effected with strings or vectors. But I created this artificial example to get my question across. however, if you strongly feel that dynamic arrays should be avoided, please feel free to share your opinion and the reasoning for it.
Result of my prior research: I was unable to find a coherent discussion on legality and morality of creating dynamic arrays using new [] and later deleting them in a different scope.
Thanks for your thoughts and insights.
My example code follows:
==========================
#include<iostream>
#include<string>
#include<cctype>
using namespace std;
void getNonPunct(string _str, char* &_npcarr, int &_npsize);
int main()
{
string input_string;
char* npchar_arr;
int npsize;
cout << "Enter any string: ";
getline(cin, input_string);
getNonPunct(input_string, npchar_arr, npsize);
// Now display non-punctuation characters in the string
cout << "string with non-punctuation characters removed:\n";
for (int n = 0; n <= npsize - 1; n++)
cout << npchar_arr[n];
cout << "\n(" << npsize << ") non-punctuation characters\n";
// Now return the memory allocated with 'new' to heap
delete [] npchar_arr;
// Is it okay to 'delete' npchar_arr eve if it was created in the function
// getNonPunct() ?
return(0);
}
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void getNonPunct(string _str, char* &_npcarr, int &_npsize)
//This void function takes an input array of strings containing arbitrary
//characters and returns a pointer to an array of characters containing only
//the non-punctuation characters in the input string. The number of
//non-punctuation characters are stored in size. Prior to the function call,
//int_arr and size are undefined. After the function call, char_arr points to
//the first location of an array of the non-punctuation character array.
//'size' is equal to the number of non-punctuation characters in the input
//string.
{
// First get the number of non-punctuation characters in the string
int str_len, npcount = 0;
str_len = static_cast<int>( _str.length() );
_npsize = 0;
for (int i = 0; i <= str_len - 1; i++)
{
if ( !ispunct(_str[i]) )
_npsize++;
}
// Now that you know how many non-punctuation characters are in the string,
// create a (dynamic) character array of _npsize.
_npcarr = new char [_npsize];
for (int k = 0; k <= str_len - 1; k++)
{
if ( !ispunct(_str[k]) )
_npcarr[npcount++] = _str[k];
}
return;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它有效吗?是的。
npchar_arr
指向的数组一直存在,直到您销毁它,并且可以在另一个函数中使用delete[]
表达式销毁它。这是一个好主意吗?不。您最好使用自动管理对象生命周期的智能指针,从而将您从手动删除指针的责任中解放出来。
如果您的编译器和标准库支持
unique_ptr
或std::auto_ptr
或 <,请考虑使用std::unique_ptr
code>std::shared_ptr 如果你不能使用unique_ptr
(shared_ptr
也可以在 Boost 和 C++ 中找到) TR1)。Is it valid? Yes. The array pointed to by
npchar_arr
exists until you destroy it and it is okay to destroy it using adelete[]
expression in another function.Is it a good idea? No. You would be much better off using a smart pointer that manages the lifetime of the object automatically, releasing you from the responsibility of
delete[]
ing the pointer manually yourself.Consider using a
std::unique_ptr<char[]>
if your compiler and Standard Library supportunique_ptr
, orstd::auto_ptr
orstd::shared_ptr
if you cannot useunique_ptr
(shared_ptr
may also be found in Boost and C++ TR1).在一个作用域中分配并在另一个作用域中删除是使用动态分配而不是自动局部变量的主要原因之一。
正如 James 所说,更喜欢使用智能指针来跟踪动态分配的对象。
我能想到的对一个作用域中的分配和另一个作用域中的释放的唯一限制是多组件应用程序,其中不同的组件是使用不同的编译器(或者可能是同一编译器的不同版本)构建的。在 Windows 上,每个编译器都提供自己的内存管理库,并且您不应从与分配内存的组件不同的组件中释放内存。或者,您可以使用 Windows 提供的所有编译器都通用的内存管理例程(例如
HeapAlloc
/HeapFree
)。在 Linux 上,每个人都使用 glibc 提供的malloc
、free
、new[]
和delete[]
,所以这不是一个问题。对于其他操作系统,您需要进行调查。Allocating in one scope and deleting in another is one of the major reasons for using dynamic allocation instead of an automatic local variable.
As James says, prefer to use smart pointers to track dynamically allocated objects.
The only constraint I can think of on allocation in one scope and deallocation in another is multi-component applications where different components are built with different compilers (or maybe different versions of the same compiler). On Windows, each compiler provides its own memory management library, and you shouldn't free memory from a different component than the one that allocated it. Or you can use Windows-provided memory management routines which are common to all compilers (e.g.
HeapAlloc
/HeapFree
). On Linux, everyone uses the glibc-suppliedmalloc
,free
,new[]
, anddelete[]
, so it isn't such an issue. For other OSes, you need to investigate.这个例子非常简单,但是想象一下你的代码的以下修改:
}
我刚刚在释放内存之前返回,这导致了内存泄漏!当然,您可能认为您永远不会做这样的事情,但是想象一个更复杂的程序,很容易犯上述错误,并且按照其他答案建议使用智能指针,可以减轻您的负担不必担心此类任务。
This example is very trivial, but image the following modification of your code:
}
I just returned before freeing the memory, which results in a memory leak! Of course, you might be thinking that you would never do such a thing, but imagine a much more complex program, it is easy to make such a mistake as the above, and using smart pointers as the other answers suggest, would alleviate you of having to worry about such tasks.