#c #linked-list
#c #связанный список
Вопрос:
У меня проблема с моим связанным списком. Я почти уверен, что мои указатели отключены, или я неправильно передал указатель, поскольку я новичок в c. Структуры также являются новыми для меня, а c — это язык, к которому я привык, и различий больше, чем я знал. Я мог бы сделать эту программу на c в кратчайшие сроки, но в любом случае вот мой код.
void add_process(struct process new_process, struct process *head, struct process *current){
new_process.next = NULL;
if(head == NULL){
head = amp;new_process;
current = head;
head->next = NULL;
}
else if(new_process.timeNeeded < head->timeNeeded){
temp = head->next;
head = amp;new_process;
new_process.next = temp;
}
else{
current = head;
while(new_process.timeNeeded > current->timeNeeded){
temp = current;
current = current->next;
}
temp->next = amp;new_process;
new_process.next = current;
}
}
Я считываю значения из файла в процесс, единственное, что я сейчас использую, это timeNeeded, который является int . И я пытаюсь упорядочить список по кратчайшему времени, необходимому в первую очередь.
int main(){
FILE *readfile;
readfile = fopen("data.txt","r");
head = NULL;
current = NULL;
while(fscanf(readfile, "%s %i %i %i",
amp;new_process.processName, amp;new_process.arrivalTime,
amp;new_process.timeNeeded, amp;new_process.priority) != EOF) {
add_process(new_process, head, current);
}
current = head;
while(current->next != NULL){
printf("%s %i %i %in", new_process.processName, new_process.arrivalTime, new_process.timeNeeded, new_process.priority);
current = current->next;
}
return 0;
}
Программа вылетает при печати, что не является проблемой. Первая проблема заключается в том, что моя программа каждый раз вводит цикл if (head == NULL) и вставляет его туда. Так что head, вероятно, никогда не меняется, но я не уверен, как это исправить, я почти уверен, что это двойной указатель, но не положительный. И я также уверен, что есть и другие проблемы, поэтому, если вы могли бы указать мне правильное направление, и если я делаю что-то совершенно неправильное, дайте мне знать.
РЕДАКТИРОВАТЬ: Итак, после добавления указателя на head я получаю сообщение об ошибке в head-> next = NULL, в котором говорится: «выражение должно иметь тип указателя на класс». Пытался добавить * перед заголовком, но, похоже, это не помогло. Кто-нибудь знает, как это исправить?
Ответ №1:
Ваша функция add_process здесь:
void add_process(struct process new_process,
struct process *head,
struct process *current)
Принимает любой указатель, который вы передаете в него по значению. Это означает, что после вашего вызова в цикле while здесь:
while(fscanf(readfile, "%s %i %i %i",
amp;new_process.processName, amp;new_process.arrivalTime,
amp;new_process.timeNeeded, amp;new_process.priority) != EOF)
{
add_process(new_process, head, current);
}
head по-прежнему будет нулевым, потому что он никогда не менялся. Чтобы он фактически изменил указатель заголовка, а не какой-либо другой указатель, измените ваш add_process, чтобы использовать указатель двойного уровня:
void add_process(struct process new_process,
struct process **head,
struct process *current)
Еще одна проблема с вашим приведенным выше кодом заключается в том, что new_process
аргумент также принимается по значению. Итак, это временная копия любого процесса, который вы передали. После add_process
возврата new_process
выходит из области видимости. Теперь это означает, что в вашем связанном списке есть висячий указатель, указывающий на недопустимую память.
Чтобы исправить это, вы должны использовать malloc для динамического выделения памяти, а затем создать копию new_process . Затем ваш связанный список указывает на malloc
процесс редактирования. Объекты, созданные в куче с помощью malloc, будут сохраняться до тех пор, пока они не будут освобождены.
Вот краткий пример, который даст вам представление:
typedef struct process Process;
void add_process(Process new_process, Process **head, Process *current)
{
Process *new_proc_copy = (Process *)malloc( sizeof(Process) );
// now copy over the stuff from
// new_process over to this one
memcpy((char *)new_proc_copy, (char *)new_proc, sizeof(Process));
if(*head == NULL)
{
*head = new_process_copy;
current = *head;
(*head)->next = NULL;
}
else if(new_process.timeNeeded < head->timeNeeded)
{
// handle this case
}
else
{
// handle rest of your stuff
}
}
Не забудьте освободить выделенную память, когда закончите. Это лучше всего сделать в вашей функции очистки процесса — эквиваленте деструктора в C , только вам нужно вызвать его вручную.
Комментарии:
1. Большое спасибо, все это имеет смысл, надеюсь, я смогу снова запустить это.
2. @user1019430 Не забудьте проголосовать за ответы, которые вы сочли полезными.
3. Да, я пытался, но сначала мне нужно 15 повторений, я дам вам право голоса, когда получу его
Ответ №2:
Чтобы иметь возможность изменять значение, содержащееся в head
, вы должны передать указатель head
на свою add_process
функцию.
Ответ №3:
Похоже, вы не выделяете место для new_process . Не могу использовать одну и ту же память каждый раз — нужно выделить немного.
Также помните, что C не изменяет параметры автоматически на по ссылке. Поэтому, если вы хотите что-то изменить, вам нужно передать указатель на эту вещь. Это включает в себя другие указатели — поэтому вам может понадобиться указатель на указатель.
Комментарии:
1. Да, я хотел спросить об этом, как мне выделить новую память на c. Я считаю, что мне нужно использовать malloc, это правильно?
2. Да, malloc — лучший способ