"...试图创建小播放列表...,...代码的重点是在结构 listOfSongs 中创建结构轨道数组,并用循环填充它..."_
当您尝试访问程序不拥有的内存区域时会导致分段错误。因为char *nazev;(和其他成员)是指针,所以下面的表达式将调用未定义的行为:
scanf("%s", sez->track[i]->nazev); //attempting to scan value into memory not owned by process.
使用前需要内存。结构中的类似成员也是如此。
简化结构的一个建议是将指针成员替换为具有合理长度的char 数组,以容纳每个成员用于的数据。
但是,由于您声明的意图是创建播放列表,另一个建议可能是使用更适合包含 播放列表 的列表结构。可以做到这一点的 C 构造通常称为linked list。
以下是链接列表形式的示例,它允许您的程序将播放列表中每个新项目的信息输入新的节点。每个新节点都通过指向下一个节点和前一个节点的指针连接,从而允许用户向前和向后遍历列表。
链表方法示例:
typedef struct track_s { //this struct contains the type information
char nazev[80]; //intended to be stored in the list
char autor[80]; //it can easily be exande to have more members
char album[80];
int orderInAlbum;
}track_s;
track_s sample_input[4] = {{"song 1 title", "name of author 1", "name of album 1", 1},
{"song 2 title", "name of author 2", "name of album 2", 2},
{"song 3 title", "name of author 3", "name of album 3", 3},
{"song 4 title", "name of author 4", "name of album 4", 4}
};
typedef struct track {
track_s track; //payload containing information to be added to list
struct track *prev;//pointers to next and previous nodes
struct track *next;
}list_tracts_s;
//prototypes
void Insert(list_tracts_s** head, track_s *new); //insert
void deleteRecord(list_tracts_s** head_ref, list_tracts_s* del); //free
int main(int argc, char *argv[])
{
list_tracts_s *head = NULL;
//populate list of nodes to contain sample input
Insert(&head, &sample_input[0]);//insert one record into one node
Insert(&head, &sample_input[1]);
Insert(&head, &sample_input[2]);
Insert(&head, &sample_input[3]);
//use list in program
//free when done (call once for each Insert
deleteRecord(&head, head);
deleteRecord(&head, head);
deleteRecord(&head, head);
deleteRecord(&head, head);
return 0;
}
void Insert(list_tracts_s** head, track_s *new)
{
/* 1. allocate node */
list_tracts_s *new_node = malloc(sizeof(*new_node));
if(new_node)
{
/* 2. assign input data */
strcpy(new_node->track.nazev , new->nazev);
strcpy(new_node->track.autor , new->autor);
strcpy(new_node->track.album , new->album);
new_node->track.orderInAlbum = new->orderInAlbum;
/* 3. Make next of new node as head and previous as NULL */
new_node->next = (*head);
new_node->prev = NULL;
/* 4. change prev of head node to new node */
if ((*head) != NULL)
(*head)->prev = new_node;
/* 5. move the head to point to the new node */
(*head) = new_node;
}
}
void deleteRecord(list_tracts_s** head_ref, list_tracts_s* del)
{
/* base case */
if (*head_ref == NULL || del == NULL)
return;
/* If node to be deleted is head node */
if (*head_ref == del)
*head_ref = del->next;
/* Change next only if node to be deleted is NOT the last node */
if (del->next != NULL)
del->next->prev = del->prev;
/* Change prev only if node to be deleted is NOT the first node */
if (del->prev != NULL)
del->prev->next = del->next;
/* Finally, free the memory occupied by del*/
free(del);
return;
}