C 为什么在打印数组时会出现分段错误?

C 为什么在打印数组时会出现分段错误?,c,memory,segmentation-fault,C,Memory,Segmentation Fault,代码如下: char* a[] = {"ls", "-l", "|", "grep", "test"}; int pipe_idx = 2; char** ptr2 = a + (pipe_idx * sizeof(char**)); printf("%s\n", *ptr2); 基本上,这只是一个演示代码。程序获取管道索引(在本例中为2)并跳到正确的位置,然后打印它 为什么会出现分段错误?ptr2指向不属于您的内存。现在,它指向a+8,因为sizeof(char**)是size

代码如下:

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

  char** ptr2 = a + (pipe_idx * sizeof(char**));
  printf("%s\n", *ptr2);
基本上,这只是一个演示代码。程序获取管道索引(在本例中为
2
)并跳到正确的位置,然后打印它


为什么会出现分段错误?

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

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

char** ptr2 = a + pipe_idx

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

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

char** ptr2 = a + pipe_idx
你应该做:

char** ptr2 = &a[pipe_idx];
指向索引(
char*
)并获取地址(
char**

甚至:

char** ptr2 = a + pipe_idx;
指针上的
+
是。通过相乘,您实际上超出了您的界限。

您应该:

char** ptr2 = &a[pipe_idx];
指向索引(
char*
)并获取地址(
char**

甚至:

char** ptr2 = a + pipe_idx;

指针上的
+
是。您的ptr2指向的内存不属于您。为什么?在我看来,正确的计算方法是sizeof(char**)是sizeof指针,而不是charok,因此sizeof(char)起了作用,但我不知道为什么。因为
sizeof(char)
是1,所以代码是
char**ptr2=a+pipe\u idx,这是正确的。指针算术为您进行乘法运算。您的ptr2指向不属于您的内存。为什么?在我看来,正确的计算方法是sizeof(char**)是sizeof指针,而不是charok,因此sizeof(char)起了作用,但我不知道为什么。因为
sizeof(char)
是1,所以代码是
char**ptr2=a+pipe\u idx,这是正确的。指针算术为你做乘法运算。我不懂DV。我遗漏了什么吗?(不是我的DV):只有在使用32位代码时;如果您使用的是64位,那么它将是+16。还有很长的路要走。乘法根本没有必要。使用
char**ptr2=a+pipe\u idx获得正确的结果-也许你应该在你的回答中这样说。我明白,我是在举一个例子,说明他的系统可能会发生什么。是的,64位可能是a+16,但我想问题是为什么OP会出现SEGFULT,我解释说我同意乘法是没有必要的,但我不能支持你的建议,因为我不知道OP真正想要打印什么。他是否要打印该数组中的第二个条目?还是他想要一种打印他想要的东西的通用方法?无论哪种方式,他都可以选择正确的方法,因为他知道他的计算是正确的。如果你不能提出正确的答案,也许你应该发表评论要求澄清?我会选择
a[2]
点位于
“|”
,因此
char**ptr2=a+pipe_idx
将给出所需的结果-可能还会添加一条注释(限定符-weasel words)“除非代码试图做其他事情,但问题没有明确说明”。我不理解DV。我遗漏了什么吗?(不是我的DV):只有在使用32位代码时;如果您使用的是64位,那么它将是+16。还有很长的路要走。乘法根本没有必要。使用
char**ptr2=a+pipe\u idx获得正确的结果-也许你应该在你的回答中这样说。我明白,我是在举一个例子,说明他的系统可能会发生什么。是的,64位可能是a+16,但我想问题是为什么OP会出现SEGFULT,我解释说我同意乘法是没有必要的,但我不能支持你的建议,因为我不知道OP真正想要打印什么。他是否要打印该数组中的第二个条目?还是他想要一种打印他想要的东西的通用方法?无论哪种方式,他都可以选择正确的方法,因为他知道他的计算是正确的。如果你不能提出正确的答案,也许你应该发表评论要求澄清?我会选择
a[2]
点位于
“|”
,因此
char**ptr2=a+pipe_idx
将给出所需的结果,并且可能会添加一条注释(限定符-weasel words)“除非代码试图做其他事情,但问题并没有说明这一点”。