【问题标题】:Why do I get segmentation fault when trying to print an array?为什么在尝试打印数组时出现分段错误?
【发布时间】:2016-09-01 23:44:24
【问题描述】:

代码如下:

char* a[] = {"ls", "-l", "|", "grep", "test"};
  int pipe_idx = 2;

  char** ptr2 = a + (pipe_idx * sizeof(char**));
  printf("%s\n", *ptr2);

基本上,这只是一个演示代码。程序获取 pipe_index(本例中为2)并跳转到正确的位置,然后打印出来。

为什么会出现分段错误?

【问题讨论】:

  • 你的 ptr2 指向一个不属于你的内存。
  • 怎么来的?在我看来是正确的计算
  • sizeof(char**) 是 sizeof 指针,而不是 char
  • 好的,所以 sizeof(char) 成功了,但我不知道为什么。
  • 因为sizeof(char)是1,所以代码是char **ptr2 = a + pipe_idx;,是正确的。指针算术为你做乘法。

标签: c memory segmentation-fault


【解决方案1】:

ptr2 指向不属于你的内存。现在,它指向a + 8,因为sizeof(char**) 是sizeof 指针,而不是char 本身。所以大小超过了你的数组大小。这是 UB,这就是为什么你会遇到段错误。

如果您尝试使用 char 指针遍历数组,则不需要像您所做的那样进行乘法运算,您只需将 pipe_idx 添加到指针上,它就会为您执行所需的算术运算。 你需要,

char** ptr2 = a + pipe_idx

【讨论】:

  • 我不懂 DV。我错过了什么吗?
  • (不是我的 DV):仅当您使用 32 位代码时;如果您使用 64 位系统,它将是 a + 16。离界还有很长的路要走。乘法根本没有必要。正确的结果是使用char **ptr2 = a + pipe_idx; 获得的——也许你应该在回答中这样说。
  • 我明白,我是在举例说明他的系统上可能发生的情况。是的,对于 64 位,它可能是 a+16,但我认为问题是为什么 OP 会出现段错误,我解释了这一点
  • 我同意不需要乘法,但我不能提倡你的建议,因为我不知道 OP 真正想要打印什么。他想打印该数组中的第二个条目吗?还是他想要一种通用的方式来打印他想要的东西?无论哪种方式,他现在都可以选择正确的方法,因为他知道他的计算是错误的
  • 如果您不能提倡正确答案,也许您应该发布 cmets 要求澄清?我会选择a[2] 指向"|",所以char **ptr2 = a + pipe_idx; 很有可能会给出想要的结果——并且可能会添加评论(限定词——黄鼠狼的话)“除非代码试图做其他事情,但问题并没有说清楚”。
【解决方案2】:

你应该这样做:

char** ptr2 = &a[pipe_idx];

指向索引 (char *) 并获取地址 (char **)。

甚至:

char** ptr2 = a + pipe_idx;

指针上的+magic。通过乘法,你实际上超出了你的界限。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-03
    • 2012-07-01
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多