C段错误

C segmentation fault

我正在尝试使用以下函数创建一个子数组:

Track * subArray(Track * arr, int start, int end){
   int size = end - start;

   Track * t = malloc(sizeof(Track) * size);

      for(int i = 0; i < size && start <= end; i++){
          t[i] = arr[start++];

      } 
}

t 指针的大小始终为 8,即使我不将它与 size 相乘并且出现分段错误也是如此。我是 C 的新手,所以我不知道是什么导致了这个异常。

我认为你的错误是你在测试中使用了 <=,而它们应该是 <。这将防止您 运行 离开数组的末尾。

这就是C难的原因。这是一个错误:您需要分配 (end-start+1) 项并在循环中使用 <=。尝试改写成这样:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Track {
  char* color;
} Track;

Track * subArray(Track* arr, int start, int end){
  assert(end > start);

  const int size = 1 + end - start;
  printf("Allocating %d items\n", size);    
  Track* t = malloc(sizeof(Track)*size);

  for(int i=start; i <= end; ++i) {
    printf("at %d fetching %d\n", i-start, i);
    t[i-start] = arr[i];
  }

  return t;
}

int main() {
  Track *track = malloc(sizeof(Track) * 7);
  track[0].color = "red";
  track[1].color = "orange";
  track[2].color = "yellow";
  track[3].color = "blue";
  track[4].color = "indigo";
  track[5].color = "green";
  track[6].color = "violet";

  Track *sub = subArray(track, 3, 5);
  printf("%s\n", sub[0].color);
  printf("%s\n", sub[1].color);
  printf("%s\n", sub[2].color);
}

编译和运行:

$ cc -g -W -Wall a.c && ./a.out
Allocating 3 items
at 0 fetching 3
at 1 fetching 4
at 2 fetching 5
blue
indigo
green

请注意,我在这里复制了 char* 指针的 。这可能会导致其他令人困惑的东西,以防万一您考虑复制我的代码(我只是起草了一些可以说明问题的东西)。

更新

您正在使用包容性索引。然而,在 C 语言中,指定起始索引和长度是很常见的。很多标准库函数都这样做,这是您最有可能在生产代码中看到的。一个原因可能是它更容易推理。在您的情况下,代码将是

Track* subArray(Track* arr, const size_t start, const size_t length) {
  Track* t = malloc(sizeof(Track) * length);

  for (size_t i = 0; i < length; ++i)
    t[i] = arr[i + start];

  return t;
}

对应的调用是

Track *sub = subArray(track, 3, 3);

在我看来,这不仅更好看;更简单易懂。

另一件常见的事情是复制指针而不是整个结构。这将取决于您的代码和数据结构的组织方式。在这种情况下,在指针数组的末尾使用一个哨兵值来标记它的结束是很常见的:这通常是一个 NULL 指针。

继续练习并继续阅读其他人的代码,您很快就会发现 C 习语和编程风格,它们会让您的生活变得更加轻松!