SSi*_*ht3 2 c++ pointers dynamic-allocation
在编写响应时,我编写了一些代码来挑战我对const指针如何工作的假设.我假设删除函数无法删除const指针,但正如您将从下面的代码中看到的那样,情况并非如此:
#include <new>
#include <string.h>
class TestA
{
private:
char *Array;
public:
TestA(){Array = NULL; Array = new (std::nothrow) char[20]; if(Array != NULL){ strcpy(Array,"Input data"); } }
~TestA(){if(Array != NULL){ delete [] Array;} }
char * const GetArray(){ return Array; }
};
int main()
{
TestA Temp;
printf("%s\n",Temp.GetArray());
Temp.GetArray()[0] = ' '; //You can still modify the chars in the array, user has access
Temp.GetArray()[1] = ' ';
printf("%s\n",Temp.GetArray());
//Temp.GetArray() = NULL //This doesn't work
delete [] Temp.GetArray(); //This works?! How do I prevent this?
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,如何将用户访问权限传递给指针(因此他们可以像char数组一样使用它),同时使删除功能无法删除它,最好是抛出某种抱怨或异常?
如果你的用户正在使用delete[]他们没有得到的指针new[],用一个线索棒击中他们的头部.
指针可以解除引用的原因有很多,但不能传递给删除:
malloc或其他一些非new分配器.其中一些将在运行时在异常中显示.其他人稍后会导致崩溃.根据标准,所有都是"未定义的行为".
delete除非另有明确说明,否则应该假设指针不能用作参数.
如果入门级程序员犯了这个错误,请教育他们.如果"经验丰富"的开发人员正在这样做,请将他们放在简历上解雇.
如果你只是想让它在他们这样做时受到伤害,那么将数组分配给一个大于必要的数组,并且return Array + 1;.如果他们试图使用,现在一切都会爆炸delete[].
实际使用是,它(更多)可能会使程序在伪造的删除调用中崩溃,而违规函数仍然在调用堆栈上.原来可能会继续运行一段时间,最后崩溃无辜的代码.所以这有助于你抓住愚蠢的用户.
delete [] Temp.GetArray(); //This works?! How do I prevent this?
Run Code Online (Sandbox Code Playgroud)
只要它返回char*或其他一些指针类型,你就无法阻止它; 如果delete语句中的表达式是const,则无关紧要,因为以下所有内容在C++中完全有效:
char *pc = f();
delete [] pc; //ok
const char *pc = g();
delete [] pc; //ok
char * const pc = h();
delete [] pc; //ok
const char * const pc = k();
delete [] pc; //ok
Run Code Online (Sandbox Code Playgroud)
但是,如果你改变这个:
char *Array;
Run Code Online (Sandbox Code Playgroud)
对此
std::vector<char> Array;
Run Code Online (Sandbox Code Playgroud)
然后你可以通过返回它来实现你想要的东西:
std::vector<char> & GetArray() { return Array; }
Run Code Online (Sandbox Code Playgroud)
底线是 :
在C++中,动态数组的默认选择应该是std::vector<T>,除非你已经非常强大的理由不使用它.