了解C ++

时间:2018-05-27 10:57:11

标签: c++ pointers segmentation-fault

Hello stackoverflow社区,我正在学习C ++中的指针。我在golang和python中有一些背景但在C或C ++中没有,所以请原谅我,因为我的理解有缺陷。让我发布一段正常工作的代码并给出段错误。

  • 1

这个打印5

int var = 5;
int *p = &var;
cout << *p << endl;
  • 2

这个也打印5

int *p;
p = &var;
cout << *p << endl;

打印5(因为p是指向int的指针,var的地址是指向int的指针。)。

然而,

  • 3

这一段错误。

int *p;
*p = var;
cout << *p << endl;

我认为是因为我将一个整数变量赋给一个变量,该变量应该是一个指向整数的指针。为什么在编译时没有显示不兼容的类型错误而不是给出分段错误?尝试这样做的程序是什么,给出了分段错误,以及如何?

  • 4

这个也是段错误

int *p;
*p = 5;
cout << *p << endl;

也会引发段错误。我对上面代码的理解是,我声明了一个指向int的指针,并且我将一个整数值赋给一个取消引用的整数指针,但由于该变量未初始化,编译器还没有在堆栈上分配内存用于存储值(类似于悬空指针行为?)如果这是原因,为什么它会引发分段错误,该错误的原因是访问程序范围之外的内存?

  • 如果仅声明变量而未初始化变量,编译器是否完全忽略变量名称并将其视为不存在的变量名称?

谢谢。

3 个答案:

答案 0 :(得分:3)

  

为什么它在编译时没有显示不兼容的类型错误   而不是给出分段错误?

因为类型兼容。 *p的类型为intvar的类型为int。你在这里处理的是运行时的问题,而不是在编译时。

  

尝试这样做的程序是什么,给出了分段错误,   怎么样?

*运算符取消引用指针。这意味着,将获取该指针的地址,并检索该地址的内容

在您的错误情况下,您将指针未初始化。因此,取消引用操作失败,因为引用的地址是不确定的。

  

如果仅声明变量而未初始化变量,编译器是否完全忽略变量名称并将其视为a   不存在的变量名?

完全没有。声明将名称引入特定范围。在您的示例中,您有 definitions :他们告诉编译器为它们分配一定的空间。

答案 1 :(得分:1)

创建指针时,它包含一些垃圾地址。当您尝试取消引用并写入某些值时,您已导致未定义的行为。 您必须在堆栈上分配一些现有变量的地址或在堆上分配内存,然后您可以取消引用它 就像你在前两个例子中所做的那样。您还可以在堆上分配一些内存,并将该内存的地址分配给指针 int *ptr = new int;
现在你可以取消引用这个指针(假设没有抛出bad_alloc异常),并为指针所指向的内存赋值。

答案 2 :(得分:1)

在上一篇文章中,你曾写过:

int *p;
*p = 5;
cout << *p << endl;

但在这种情况下,您尚未为p指定值。在使用之前,必须为指针赋值。你可以尝试如下:

int *p;
p = &var; //or another address of integer variable
*p = 5;
cout << *p << endl;

简而言之,我想强调一下,在使用之前必须为指针赋值。