相关疑难解决方法(0)

何时在null实例上调用成员函数会导致未定义的行为?

请考虑以下代码:

#include <iostream>

struct foo
{
    // (a):
    void bar() { std::cout << "gman was here" << std::endl; }

    // (b):
    void baz() { x = 5; }

    int x;
};

int main()
{
    foo* f = 0;

    f->bar(); // (a)
    f->baz(); // (b)
}
Run Code Online (Sandbox Code Playgroud)

我们期望(b)崩溃,因为x空指针没有相应的成员.在实践中,(a)不会崩溃,因为this从不使用指针.

因为(b)取消引用this指针((*this).x = 5;),并且this为null,程序进入未定义的行为,因为取消引用null总是被称为未定义的行为.

(a)导致未定义的行为吗?如果两个函数(和x)都是静态的呢?

c++ standards-compliance null-pointer undefined-behavior language-lawyer

115
推荐指数
2
解决办法
1万
查看次数

C++静态const通过NULL指针访问

class Foo {
public:
 static const int kType = 42;
};

void Func() {
 Foo *bar = NULL;
 int x = bar->kType;
 putc(x, stderr);
}
Run Code Online (Sandbox Code Playgroud)

这是定义的行为吗?我阅读了C++标准但是找不到任何关于访问静态const值的内容......我已经检查了GCC 4.2,Clang ++和Visual Studio 2010生成的程序集,并且它们都没有执行NULL的解引用指针,但我想确定.

c++ static pointers

12
推荐指数
1
解决办法
1919
查看次数

是否取消引用一个等于nullptr标准的未定义行为的指针?

一位博客作者提出了有关空指针解除引用的讨论:

我在这里提出一些反驳论点:

他引用标准的主要推理理由是:

当'podhd'是空指针时,'&podhd-> line6'表达式在C语言中是未定义的行为.

C99标准说明了以下关于'&'地址的运算符(6.5.3.2"地址和间接运算符"):

一元&运算符的操作数应该是函数指示符,[]或一元*运算符的结果,或者是一个左值,它指定一个不是位字段的对象,并且不用寄存器存储类说明符声明.

表达式'podhd-> line6'显然不是函数指示符,是[]或*运算符的结果.这是一个左值表达式.但是,当'podhd'指针为NULL时,表达式不指定对象,因为6.3.2.3"Pointers"表示:

如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与指向任何对象或函数的指针进行比较.

当"左值在评估时未指定对象时,行为未定义"(C99 6.3.2.1"左值,数组和函数指示符"):

左值是具有对象类型或除void之外的不完整类型的表达式; 如果左值在评估时未指定对象,则行为未定义.

所以,同样的想法简要说明:

当在指针上执行 - >时,它会计算到没有对象存在的左值,因此行为是未定义的.

这个问题纯粹是基于语言的,我不会问一个给定的系统是否允许用任何语言篡改地址0的内容.

据我所知,取消引用一个值等于的指针变量没有限制nullptr,甚至认为指针与nullptr(或(void *) 0)常量的比较在某些情况下可能会因为所述段落而在优化中消失,但这看起来像另一个问题是,它不会阻止取消引用其值等于的指针nullptr.请注意,我已经检查了其他SO问题和答案,我特别喜欢这组引用,以及上面的标准引号,我没有偶然发现一些明显从标准中推断出如果指针ptr比较等于nullptr,取消引用这将是未定义的行为.

我得到的最多是将常量(或其转换为任何指针类型)引用的是UB,但没有任何关于变量等于从中得到的值的变量nullptr.

我想清楚地将nullptr常量与保持值等于它的指针变量分开.但解决这两种情况的答案都是理想的.

我确实意识到,当进行比较nullptr等时,优化可以快速进行,并且可以简单地基于此来剥离代码.

如果结论是,如果ptr等于nullptr解除引用的值肯定是UB,另一个问题如下:

C和C++标准是否意味着地址空间中的特殊值必须仅存在才能表示空指针的值?

c c++ language-lawyer

9
推荐指数
2
解决办法
6117
查看次数

是否在NULL指针上调用函数未定义?

可能重复:
何时在null实例上调用成员函数会导致未定义的行为?
C++标准:解除引用NULL指针以获取引用?

说我有班级:

class A
{
public:
   void foo() { cout << "foo"; }
};
Run Code Online (Sandbox Code Playgroud)

并像这样调用foo:

A* a = NULL;
a->foo();
Run Code Online (Sandbox Code Playgroud)

我怀疑这会调用未定义的行为,因为它等同于(*a).foo()(或者它是?),并且取消引用a NULL UB,但我找不到引用.谁能帮我吗?还是定义了?

不,功能不是virtual.不,我没有访问任何成员.

编辑:我投票结束这个问题,但不会删除它,因为我自己找不到副本,我怀疑这个标题可能更容易被其他人找到.

c++ undefined-behavior

8
推荐指数
1
解决办法
3041
查看次数

什么是常见的C/C++宏来确定结构成员的大小?

在C/C++中,如何确定结构的成员变量的大小,而无需定义该结构类型的虚拟变量?这是一个如何做错的例子,但显示了意图:

typedef struct myStruct {
  int x[10];
  int y;
} myStruct_t;

const size_t sizeof_MyStruct_x = sizeof(myStruct_t.x);  // error
Run Code Online (Sandbox Code Playgroud)

作为参考,如果你首先定义一个虚拟变量,这应该是如何找到'x'的大小:

myStruct_t dummyStructVar;

const size_t sizeof_MyStruct_x = sizeof(dummyStructVar.x);
Run Code Online (Sandbox Code Playgroud)

但是,我希望避免为了获得'x'的大小而创建一个虚拟变量.我认为有一种聪明的方法可以将0重新设置为myStruct_t,以帮助找到成员变量'x'的大小,但是已经足够长,以至于我忘记了细节,似乎无法在这方面获得良好的Google搜索.你知道吗?

谢谢!

c++ sizeof

4
推荐指数
2
解决办法
4429
查看次数

虽然unique_ptr保证在移动后存储nullptr,但它仍指向对象?

我用GCC 5.2(C++ 11)测试了以下代码:

#include <iostream>
#include <memory>

struct Foo
{
    Foo()      { std::cout << "Foo::Foo\n";  }
    ~Foo()     { std::cout << "Foo::~Foo\n"; }
    void bar() { std::cout << "Foo::bar\n";  }
};

void f(const Foo &)
{
    std::cout << "f(const Foo&)\n";
}

int main()
{
    std::unique_ptr<Foo> p1(new Foo);  // p1 owns Foo
    if (p1) p1->bar();

    {
        //p1->bar();
        std::unique_ptr<Foo> p2(std::move(p1));  // now p2 owns Foo
        f(*p2);
        p1->bar();
        if(p1==nullptr)
        {
            std::cout<<"NULL"<<std::endl;
        }
        p1 = std::move(p2);  // ownership returns to p1
        std::unique_ptr<Foo> p3;
        p3->bar();
        std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ unique-ptr c++11

1
推荐指数
1
解决办法
242
查看次数

这是C++中的未定义行为从悬空指针调用函数

这里出现了一个问题,当一个指针变得晃来晃去时,问"为什么这个工作".答案是它是UB,这意味着它可能起作用.

我在一个教程中学到了:

#include <iostream>

struct Foo
{
    int member;
    void function() { std::cout << "hello";}

};

int main()
{
    Foo* fooObj = nullptr;
    fooObj->member = 5; // This will cause a read access violation but...
    fooObj->function(); // Because this doesn't refer to any memory specific to
                        // the Foo object, and doesn't touch any of its members
                        // It will work.
}
Run Code Online (Sandbox Code Playgroud)

这相当于:

static void function(Foo* fooObj) // Foo* essentially being the "this" pointer
{
    std::cout << "Hello";
    // Foo …
Run Code Online (Sandbox Code Playgroud)

c++ pointers undefined-behavior dangling-pointer

1
推荐指数
1
解决办法
182
查看次数

std::uniform_int_distribution 的分段错误

我有一个包含多个类的程序,其中一些需要随机双精度和整数。在其中一个类中,我定义了一个结构来为随机引擎提供种子,并且能够在需要时通过该结构的对象生成随机实数和整数。带有类和结构声明的 .hpp 文件如下所示:

struct RNG {
public:
    static std::mt19937 gen;
    static std::uniform_int_distribution<uint32_t> dist_ui;
    static std::uniform_real_distribution<double> dist_d;
    uint32_t r_ui = dist_ui(gen);
    double r_d = dist_d(gen);
private:
    static unsigned seed;
};

class A {
private:
    uint32_t a_;
public:
    A();
};
Run Code Online (Sandbox Code Playgroud)

.cpp 文件如下所示:

#include "A.hpp"

unsigned RNG::seed = 42;
std::mt19937 RNG::gen(RNG::seed);
std::uniform_int_distribution<uint32_t> RNG::dist_ui(1, std::numeric_limits<uint32_t>::max());
std::uniform_real_distribution<double> RNG::dist_d(0.0,1.0);

A::A() {
    RNG* r;
    a_ = r->dist_ui(r->gen);
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我调用uniform_real_distribution

r->dist_d(r->gen)
Run Code Online (Sandbox Code Playgroud)

一切正常。但是,如果我调用uniform_int_distribution

r->dist_ui(r->gen)
Run Code Online (Sandbox Code Playgroud)

与上面的代码片段一样,我遇到了分段错误。如果我仅使用 int dist 而不是 real 和 int 来定义结构,或者将 int dist 的边界更改为 [0,100) 或其他任何内容,也会发生错误。有谁知道这里发生了什么?我感谢任何帮助!

编辑:如果我像这样访问非静态成员,我会得到同样的错误

RNG …
Run Code Online (Sandbox Code Playgroud)

c++ random segmentation-fault c++11

1
推荐指数
1
解决办法
337
查看次数

在类的NULL指针实例上调用方法是否可以?

这个C++代码适用于我的平台和编译器(Windows,GCC 4.7):

#include <stdio.h>

class A {
public:

    /* ... */

    int size() const
    {
        if ( this == NULL ) {
            return 0;
        }
        return m_size;
    }

private:
    int m_size;
};

int main()
{
    A* a = NULL;

    printf( "%d\n", a->size() );
}
Run Code Online (Sandbox Code Playgroud)

但这段代码是有效的标准C++还是可移植的?方法接受这个== NULL是否合适?

c++

-4
推荐指数
1
解决办法
157
查看次数