Java 这些指针错误在C++;vs管理

Java 这些指针错误在C++;vs管理,java,c++,exception,pointers,managed,Java,C++,Exception,Pointers,Managed,为了更好地理解这些错误及其运行时或编译结果之间的语义差异,我将此作为一个社区wiki。另外,我在java上编码太长了,我想在C++中更好地学习指针——所以我需要其他人来做。 Edit2:我正在重构这个问题。我试图指出的区别是,在托管代码上,这些错误都是通过异常统一处理的。然而,C++不是那么简单——我想了解,在每种情况下,您是否都可能会得到错误、Sebug、可恢复行为或更糟的传播的无声错误。请看我的新的具体例子(是的,我知道答案总是“与代码完全一致”;毕竟我是一名程序员。我想知道你经常遇到的有趣

为了更好地理解这些错误及其运行时或编译结果之间的语义差异,我将此作为一个社区wiki。另外,我在java上编码太长了,我想在C++中更好地学习指针——所以我需要其他人来做。 Edit2:我正在重构这个问题。我试图指出的区别是,在托管代码上,这些错误都是通过异常统一处理的。然而,C++不是那么简单——我想了解,在每种情况下,您是否都可能会得到错误、Sebug、可恢复行为或更糟的传播的无声错误。请看我的新的具体例子(是的,我知道答案总是“与代码完全一致”;毕竟我是一名程序员。我想知道你经常遇到的有趣细节。)

Edit3:在下文中,我所说的“类”是指类的实例。谢谢

错误1: 指针值为NULL,也称为指针==0

  • 托管代码:在运行时引发NullPointerException
  • C++::
  • 示例:嗯,duh,您有一个指向类的指针,但它被初始化为0。将其发送到函数时会发生什么情况。C++没有留下任何类的指示;它只是公共“占位符”的串联
错误2: 指针指向内存中值为NULL或==0的前一个类

  • 托管代码:不允许通过内存模型。所有引用的对象都保留在内存中。没有例外情况吗
  • C++::
  • 示例:您有一个指向类的指针,该类被删除。然后将指针作为参数传递给函数。显然,出现的问题取决于函数如何处理指向类。我的问题是:STL上是否有故障保护处理?一个好的专有图书馆?平均开源代码
错误3:指针指向的类不是正确的类或子类

  • 托管代码:抛出ClassCastException
  • C++:[correct if error]编译器试图通过不允许错误类型转换来解决这个问题。然而,如果这是在运行时发生的,我假定是未定义的行为。是否存在类似类对象的情况,这些情况不会总是爆发
  • 示例:指针被错误地重新分配,使其值完全等于另一个类。我假设您将这个引用类传递给的函数将盲目地获取它引用的任何实例变量的偏移量。因此,它错误地解释了原始二进制文件。在C++中没有办法阻止这个吗?和/或。。。在任何情况下,这种能力都会被好好利用吗
错误4:指针指向类中间(未对齐)或未初始化的垃圾

  • 托管代码:内存模型不允许
  • C++:等同于案例3
  • 例子:你经常合法地使用这个。例如,您可以直接访问STL向量的数组-这是指向类的中间。然而,似乎同样容易“错过”?是否存在一个常见的陷阱,您可能会违背自己的意愿发生这种情况,例如加载的库与您链接的库不同(是否有防止这种情况发生的机制?)

提前感谢所有贡献者。

大多数贡献者会导致不可预测的行为。引用史蒂夫·麦康奈尔(Steve McConnell)的《代码全集》第二版“使用指针本身就很复杂,正确使用指针需要您对编译器的内存管理方案有很好的了解”。

其中大多数会导致不可预测的行为。引用史蒂夫·麦康奈尔(Steve McConnell)的《代码全集》(Code Complete第二版)“使用指针本质上是复杂的,正确使用指针需要您对编译器的内存管理方案有很好的理解。”

#2、#3和#4可能会起作用,这取决于该方法尝试执行的操作。记住,在C++中,类代码只存储一次(并且与实例数据分开,这是对象指针引用的),因此可以在内存的随机块上调用类方法。例如,以下打印“-1”(使用g++4测试):

#包括
福班
{
公众:
int x;
void foo()
{
std::cout#1应该抛出一个segfault

< P>>2,3,和5月4日的工作,取决于方法试图做什么。记住,C++中,类代码只存储一次(并且与实例数据分开,这是对象指针引用的),因此可以在内存的随机块上调用类方法。例如,下面的打印“-1”(用G+ 4测试):

#包括
福班
{
公众:
int x;
void foo()
{

Windows错误1下的std::cout将导致针对访问冲突引发结构化(win32)异常,因为您试图访问一个您没有读取权限的虚拟内存页。Unix派生的操作系统具有类似的机制,尽管使用不同的术语


这是定义明确的(如果通常不受欢迎!)行为,并可能被结构化异常处理程序捕获。通常,托管运行时将依赖于引发此异常的底层操作系统,然后对其进行处理并将其转换为托管异常。这比在跟踪之前检查每个指针访问是否为空要高效得多。

在Windows错误1下会导致当您试图访问没有读取权限的虚拟内存页时,将针对访问冲突引发结构化(win32)异常。Unix派生的操作系统具有类似的机制,尽管术语不同

这是定义良好的行为(如果通常不受欢迎!),并且可以被结构化异常处理程序捕获
#include <iostream>

class Foo
{
public:
    int x;
    void foo()
    {
        std::cout << x << std::endl;
    }
};

int main(void)
{
    void* mem = malloc(1024);
    memset(mem, 0xff, 1024);
    Foo* myFoo = (Foo*)mem;
    myFoo->foo();
    return 0;
}