【问题标题】:Why does command line argument declaration cause segmentation fault为什么命令行参数声明会导致分段错误
【发布时间】:2017-07-27 04:04:51
【问题描述】:

我很困惑。经阅读this 和this

我决定试一试,所以我坐下来写了一个看起来像这样的原版代码

#include <stdio.h>
int main()
{

  int *ptr;
  printf("%p\n:",ptr);
  *ptr = 65;
  printf("PTR : \n \t VALUE: %d\n \t ADDRESS: %p\n",*ptr,ptr);
  return 0;
}

它奏效了。

0x7fff50ba0500
:PTR :
     VALUE: 65
     ADDRESS: 0x7fff50ba0500

现在,我有几个(准确地说是 3 个)问题。

问题 1:

我知道int *ptr 没有在上述步骤中初始化。其中一种方法是使用。

 int *ptr = malloc(sizeof(int));
 *ptr = 65

   or 
 int b = 65;
 int *ptr;
 ptr = &b; // or simply int *ptr = &b;

但与 char 指针不同,它不能直接赋值。 char 指针世界中的示例

   char *name = "apple";
   or
   char *name;
   name = "viren";

是一个有效的声明,但对于其他示例,以下内容不正确

   int *ptr = 65; // not valid, since ptr should point to address.

对此有何解释?

问题 2

正如其他堆栈溢出答案中提到的那样

*ptr = 65;

不好,因为 ptr 必须指向一个地址。在上述情况下,它将指向0x41 地址(如果通过转换为十六进制是正确的)因此代码将导致segmentation fault

那么为什么上面的代码会中断并导致Segmentation Fault。

问题 3: 我有不写命令行参数声明的习惯,即

即

int main(int argc,char *argv[])

在我第一次成功运行代码没有命令行声明之后。 (令我惊讶的是,它取得了成功)。我添加了命令行参数声明。

但是,这次运行相同的代码。导致分段错误。

问题:那么为什么代码在没有命令行参数的情况下工作但与命令行参数声明中断。

【问题讨论】:

  • 这些问题完全不相关。选择一个,或将它们分成不同的问题。
  • 一个提示:int * ptr = y 与 int ptr; 相同,后跟 (1) ptr = y; 或 (2) *ptr = y;?这两个作业有什么区别?
  • *ptr = 65 当ptr 指针未初始化时是未定义的行为。您问题中最好的部分是尝试定义未定义,这完全没有意义。

标签: c pointers


【解决方案1】:

答案 1:

当您执行char *name = "apple"; 时,您指定name 是指向字符串文字对象“apple”的字符指针。在 C 中,字符串文字存储在内存的特殊(只读)部分中。所以name 这里指向存储文字“apple”的内存部分。

但是,整数或浮点字面量通常是机器指令的一部分,不会单独存储在内存中。所以你的声明 int * p = 65 变得无效,因为整数文字 65 没有单独存储在内存中,因此 int 指针没有可以指向的地址。

答案 2:

您的理解并不完全正确。语句*ptr = 65 指示应将int 值65 存储在ptr 指向的地址中。在您的情况下,由于您尚未使用可写内存初始化 ptr,因此它会引发分段错误。

答案 3:

为main 函数指定参数不应与您看到的分段错误有任何关系。为未初始化的指针赋值的行为是不可预测的。它可能会抛出分段错误,也可能不会,这取决于它最终写入的内存位置是否可写。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 2020-04-15
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2011-05-31
    • 2020-10-28
    相关资源
    最近更新 更多