为什么命令行参数声明会导致分段错误

时间:2017-03-07 04:02:11

标签: c pointers

我很困惑。阅读thisthis

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

#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

如在其他StacK溢出答案中提到的那样

*ptr = 65;

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

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

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

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

第一次成功运行代码而没有命令行声明。 (这让我的成功更令我惊讶)。我添加了命令行参数声明。

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

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

1 个答案:

答案 0 :(得分:2)

回答1

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

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

回答2

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

回答3

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