标签: null-pointer

如何防止从'0`构造std :: string引起的麻烦?

void foo (const std::string &s) {}

int main() {
  foo(0);   //compiles, but invariably causes runtime error
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器(g ++ 4.4)显然通过调用来解释0char* NULL和构造.这当然没用,因为指针不是指向c-string的有效指针.当我尝试调用时,这种误解不会出现,这有助于产生编译时错误.sstring::string(const char*, const Allocator &a = Allocator())NULLfoo(1)

当我不小心调用类似的函数时,是否有可能在编译时得到这样的错误或警告

void bar(const std::string &s, int i=1);
Run Code Online (Sandbox Code Playgroud)

bar(0),忘记了string,实际上有意义i=0

c++ string g++ null-pointer

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

是对空指针未定义行为执行算术?

它看起来像下面的程序计算一个无效的指针,因为NULL除了赋值和比较相等之外没有任何好处:

#include <stdlib.h>
#include <stdio.h>

int main() {

  char *c = NULL;
  c--;

  printf("c: %p\n", c);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

然而,似乎GCC或Clang针对未定义行为的警告或工具都没有说这实际上是UB.这个算术实际上是否有效,而且我太迂腐了,或者这是我们应该报告的检查机制的缺陷吗?

测试:

$ clang-3.3 -Weverything -g -O0 -fsanitize=undefined -fsanitize=null -fsanitize=address offsetnull.c -o offsetnull
$ ./offsetnull
c: 0xffffffffffffffff

$ gcc-4.8 -g -O0 -fsanitize=address offsetnull.c -o offsetnull
$ ./offsetnull 
c: 0xffffffffffffffff
Run Code Online (Sandbox Code Playgroud)

似乎很好地记录了Clang和GCC使用的AddressSanitizer更侧重于解除坏指针的引用,所以这很公平.但其他检查也没有抓住它: - /

编辑:我问这个问题的部分原因是-fsanitize标志能够动态检查生成的代码中的良好定义.这是他们应该抓住的东西吗?

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

18
推荐指数
3
解决办法
3456
查看次数

(int*)0是否为空指针?

这可以被认为是这个问题的扩展(我只对C感兴趣,但添加C++来完成扩展)

6.3.2.3.3中的C11标准说:

值为0的整型常量表达式或此类表达式转换为类型void *称为空指针常量.

我个人对此的看法是0并且(void *)0表示空指针,其整数值实际上可能不是0,但是不包括0强制转换为任何其他类型.

但是,标准然后继续:

如果将空指针常量转换为指针类型,则生成的指针称为空指针,...

它包含(int *)0为空指针,因为强制转换是一种显式转换(C11,6.3),它在转换方法下列出.

然而,令我惊讶的是以下短语

...或者这样的表达式转换为void *...

有了上面的语义,这句话​​似乎完全没用.问题是,这句话完全没用吗?如果没有,它有什么影响?因此,是否(int *)0为空指针?


另一个可以帮助讨论的问题如下.被(long long)123视为"123转换为long long",或"123与类型long long".换句话说,有没有转换(long long)123?如果没有,则上面的第二个引用包括(int *)0为空指针.

c null-pointer language-lawyer

18
推荐指数
2
解决办法
8331
查看次数

每个空指针常量都是空指针吗?

来自 C17 草案 (6.3.2.3 \xc2\xb63):

\n
\n

值为 0 的整型常量表达式,或此类转换为类型的表达式void *,称为空指针常量67)如果将空指针常量转换为指针类型,则生成的指针(称为空指针)保证与任何对象或函数的指针比较不相等。

\n

67)该宏NULL在(和其他标头)中定义<stddef.h>为空指针常量 [...]。

\n
\n

由此可见,以下是空指针常量0, 0UL, (void *)0, (void *)0UL, NULL

\n

进一步得出以下是空指针(int *)0, (int *)0UL, (int *)(void *)0, (int *)(void *)0UL, (int *)NULL。有趣的是,这些都不是“空指针常量”;看这里

\n

以下空指针常量空指针(因为void *是指针类型,并且00UL是空指针常量):(void *)0 …

c void-pointers null-pointer language-lawyer

18
推荐指数
4
解决办法
5037
查看次数

以下哪个会创建空指针?

标准说,取消引用空指针会导致未定义的行为.但是什么是"空指针"?在下面的代码中,我们称之为"空指针":

struct X
{
  static X* get() { return reinterpret_cast<X*>(1); }
  void f() { }
};

int main()
{
  X* x = 0;
  (*x).f(); // the null pointer?  (1)

  x = X::get();
  (*x).f(); // the null pointer?  (2)

  x = reinterpret_cast<X*>( X::get() - X::get() );
  (*x).f(); // the null pointer?  (3)

  (*(X*)0).f(); // I think that this the only null pointer here (4)
}
Run Code Online (Sandbox Code Playgroud)

我的想法是,只有在最后一种情况下才会取消引用空指针.我对吗?根据C++标准,编译时空指针和运行时之间是否存在差异?

c++ null-pointer dereference

14
推荐指数
3
解决办法
9907
查看次数

NULL宏或NULL const

我目前正在阅读一本关于C++的书,在本书中,作者解释说使用常量而不是NULL宏更好,但没有真正解释为什么或给出任何优点或缺点.

那么为什么最好使用:

const int NULL = 0;
int *ptr = NULL;
Run Code Online (Sandbox Code Playgroud)

代替:

int *ptr = NULL;
Run Code Online (Sandbox Code Playgroud)

唯一的解释是NULL宏不是类型安全的.

c++ null-pointer

14
推荐指数
2
解决办法
2938
查看次数

不评估应用sizeof的表达式使得在C++中取消引用sizeof内的null或无效指针是合法的吗?

首先,我已经看到了关于C99的这个问题,并且接受的答案参考操作数未在C99标准草案中评估.我不确定这个答案是否适用于C++ 03.还有一个关于C++的问题,引用了类似措辞的答案,并且在某些情况下,还会出现未评估的操作数.未评估未评估的操作数.措辞.

我有这个代码:

 int* ptr = 0;
 void* buffer = malloc( 10 * sizeof( *ptr ) );
Run Code Online (Sandbox Code Playgroud)

问题是 - 里面是否有空指针取消引用(以及UB)sizeof()

C++ 03 5.3.3/1表示sizeof运算符产生其操作数的对象表示中的字节数.操作数是表达式(未计算)或带括号的type-id.

链接到答案引用这个或类似的措辞,并使用"未评估"部分推断出没有UB.

但是,在这种情况下,我无法找到标准链接评估的确切位置与是否具有UB.

"不评估"应用sizeof的表达式使得在C++中取消引用sizeof中的null或无效指针是合法的吗?

c++ sizeof null-pointer undefined-behavior language-lawyer

13
推荐指数
2
解决办法
860
查看次数

通过解除引用NULL指针来分配引用

int&  fun()
{
    int * temp = NULL;
    return *temp;
}
Run Code Online (Sandbox Code Playgroud)

在上面的方法中,我试图取消引用NULL指针.当我调用此函数时,它不会给出异常.我发现当返回类型是引用时它不会给出异常,如果它是按值,那么它.即使将NULL指针的解引用引用为引用(如下面的行),它也不会给出.

int* temp = NULL:
int& temp1 = *temp;
Run Code Online (Sandbox Code Playgroud)

在这里我的问题是,在引用的情况下编译器是否进行解除引用?

c++ pointers reference null-pointer undefined-behavior

12
推荐指数
2
解决办法
5451
查看次数

Android - 处理屏幕方向更改的对话框

我重写了onCreateDialog和onPrepareDialog方法或Dialog类.

我按照Reto Meier的专业Android应用程序开发书第5章中的示例来提取一些XML数据,然后使用对话框显示信息.

我基本上完全遵循了它,但更改了变量以适合我自己的XML模式,如下所示:


@Override
public Dialog onCreateDialog(int id) {
  switch(id) {
    case (SETTINGS_DIALOG) :        
      LayoutInflater li = LayoutInflater.from(this);
      View settingsDetailsView = li.inflate(R.layout.details, null);

      AlertDialog.Builder settingsDialog = new AlertDialog.Builder(this);
      settingsDialog.setTitle("Provisioned Settings");         
      settingsDialog.setView(settingsDetailsView);
return settingsDialog.create();
  }
  return null;
}

@Override
public void onPrepareDialog(int id, Dialog dialog) {
  switch(id) {
    case (SETTINGS_DIALOG) :                  

String afpunText = "  ";

     if(setting.getAddForPublicUserNames() == 1){
      afpunText = "Yes";
     }
     else{
      afpunText = "No";
     }
      String Text = "Login Settings: " + "\n" 
                       + "Password: " + …
Run Code Online (Sandbox Code Playgroud)

android dialog null-pointer screen-orientation

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

为什么 C++ 的 NULL 是整数文字而不是像 C 中的指针?

我已经编写 C++ 多年,nullptr用于空指针。我也知道 C,从那里 NULL 起源,并记住它是一个空指针的常量,类型void *

出于NULL某些原因,我不得不在我的 C++ 代码中使用某些东西。好吧,想象一下当在一些模板参数推导过程中编译器告诉我我的 NULL 真的是一个......长时我的惊讶。所以,我仔细检查了:

#include <type_traits>
#include <cstddef>

static_assert(not std::is_same<decltype(NULL), long>::value, "NULL is long ???");
Run Code Online (Sandbox Code Playgroud)

事实上,静态断言失败(使用 GCC 和 clang)。

cppreference.com 上检查,果然(C++11 措辞):

宏 NULL 是一个实现定义的空指针常量,它可以是一个值为 0 的整数文字,或者一个类型为 的纯右值std::nullptr_t

为什么这是有道理的?就其本身而言,鉴于 C 的不兼容性?

c c++ cross-language null-pointer nullptr

9
推荐指数
4
解决办法
296
查看次数