好吧,我想我们都同意以下代码所发生的事情是未定义的,具体取决于传递的内容,
void deleteForMe(int* pointer)
{
delete[] pointer;
}
Run Code Online (Sandbox Code Playgroud)
指针可以是各种不同的东西,因此delete[]对它执行无条件是未定义的.但是,让我们假设我们确实传递了一个数组指针,
int main()
{
int* arr = new int[5];
deleteForMe(arr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,在这种情况下,指针是一个数组,谁知道这个?我的意思是,从语言/编译器的角度来看,它不知道arr数组指针是否指向单个int的指针.哎呀,它甚至不知道是否arr是动态创建的.但是,如果我做以下事情,
int main()
{
int* num = new int(1);
deleteForMe(num);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
操作系统足够聪明,只能删除一个int,而不是通过删除超出该点的其余内存来进行某种类型的"杀戮狂欢"(与strlen非\0终结字符串形成对比- 它将一直持续到它点击0).
那么他们的工作是记住这些东西吗?操作系统是否在后台保留某种类型的记录?(我的意思是,我意识到我开始这篇文章时说过发生的事情是未定义的,但事实是,'杀戮狂欢'的情况不会发生,所以因此在实际世界中有人记得.)
我认为在重新分配动态分配的指针时,我们都理解删除的必要性,以防止内存泄漏.但是,我很好奇,C++在多大程度上强制要求使用delete?例如,采取以下计划
int main()
{
int* arr = new int[5];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
虽然所有意图和目的都没有发生泄漏(因为你的程序结束了,操作系统会在它返回后清理所有内存),但标准是否还需要 - 或建议 - 在这种情况下使用delete [] ?如果没有,还有其他原因你会在这里删除[]吗?
最近我和一位几个月前开始上C++课程的朋友(他第一次接触编程)谈话.我们总体上讨论了C#和.NET的主题,他向我指出,他觉得它对于所有常见问题(低速,易碎的字节码等)都是"注定要失败的".我在所有这些问题上都同意了他,但我拒绝说它注定要失败,只是因为我觉得,像C#这样的语言可能会成为本机代码(如果微软选择改变.NET的实现方式)字节码,JIT运行时环境直接编译为本机代码,就像你的C++程序一样).
我的问题是,我出去吃午饭吗?我的意思是,它可能需要做很多工作(并且可能会破坏太多东西),但是没有某种类型的魔法障碍阻止C#代码本地编译(如果有人想这样做),对吧?曾经有一段时间,C++被认为是一种非常高级的语言(它仍然是,但不像过去那么多),但现在它已成为微软原生API的基石(连同C).在某种程度上,.NET在某种程度上与C++处于同一水平的想法似乎只是时间和精力问题,而不是语言设计中的一些根本缺陷.
编辑:我应该补充一点,如果.NET的本机编译成为可能,为什么微软选择不去那条路?为什么他们选择了JIT字节码路径?