Получение ошибки сегментации при попытке доступа к функции - PullRequest
1 голос
/ 07 марта 2019

Я полагаю, что ошибка сегментации происходит в моем операторе If, но я не уверен, почему это так, что при использовании теста он, кажется, даже не попадает в оператор If при тестировании, если knapsack == NULL, он даже не переходит к следующему printf заявление. Могу ли я не проверить рюкзак на равенство NULL, хотя мой основной элемент передает NULL в рюкзак? Только Knapsack.c можно редактировать в соответствии со спецификациями. Knapsack.h и Knapsack-testcase1.c были переданы мне и СПЕЦИАЛЬНО запрещены для редактирования.

Knapsack.h

/* knapsack.h
 * implements simple knapsack data structure as a linked list 
 * NOTE: a function may update the value of input argument *knapsack if it changes the first node of the knapsack to another node. Such a change include the case when an item is added to an empty knapsack
 */

typedef struct listitem* listitemptr;

struct listitem {
  int item;           // actual int item
  unsigned int count; // number of the same item in the knapsack; should be >= 1
  listitemptr next;   // pointer to next item 
};

listitemptr KnapsackAdd(listitemptr *knapsack, int item);    
int KnapsackRemove(listitemptr *knapsack, int item);
void KnapsackPrint(const listitemptr *knapsack);
unsigned int KnapsackItemCount(const listitemptr *knapsack, int item);
unsigned int KnapsackSize(const listitemptr *knapsack);

Knapsack.c

#include "knapsack.h"
#include <stdio.h>
#include <stdlib.h>

listitemptr KnapsackAdd(listitemptr *knapsack, int item){
   if(*knapsack==NULL){//empty list
       listitemptr newest= (listitemptr) malloc(sizeof(struct listitem));
       newest->item=item;
       newest->count=1;
       newest->next=NULL;
       return newest;
   }else{
       listitemptr temp=*knapsack;
       listitemptr previous=NULL;
       while(temp!=NULL){
           if(temp->item == item){
               temp->count=temp->count+1;
               break;
           }
           previous=temp;
           temp=temp->next;
       }
       if(temp==NULL){
           listitemptr newest= (listitemptr) malloc(sizeof(struct listitem));
           newest->item=item;
           newest->count=1;
           newest->next=NULL;
           previous->next=newest;
           return newest;
       }
       return temp;
   }
}

int KnapsackRemove(listitemptr *knapsack, int item){
   if(*knapsack==NULL)
       return -1;
   listitemptr present=*knapsack;
   listitemptr previous=NULL;

   while(present!=NULL){
       if(present->item==item){
           if(present->count>1){
               present->count=present->count-1;
           }else{
               if(previous==NULL){ //delete at head
                   *knapsack=present->next;
               }else{
                   previous->next=present->next;
                   free(present);
               }
           }
           break;
       }
       previous=present;
       present=present->next;
   }

   return 0;
}

void KnapsackPrint(const listitemptr *knapsack){
   if(*knapsack==NULL)
       printf("(nothing)\n");
   else{
       listitemptr temp=*knapsack;
       while(temp!=NULL){
           printf("%d (%d), ",temp->item,temp->count);
           temp=temp->next;
       }
       printf("\n");
   }
}

unsigned int KnapsackItemCount(const listitemptr *knapsack, int item){
   if(*knapsack==NULL)
       return 0;
   listitemptr temp=*knapsack;
   while(temp!=NULL){
       if(temp->item==item)
           return temp->count;
       temp=temp->next;
   }
   return 0;  
}

unsigned int KnapsackSize(const listitemptr *knapsack){
    printf("saada\n");
   if(*knapsack==NULL){
    printf("testing\n");
       return 0;
   }

   listitemptr temp=*knapsack;
   unsigned int sum=0;
   while(temp!=NULL){
       sum+=temp->count;
       temp=temp->next;
   }
   return sum;

ранец-testcase1.c

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

#include "knapsack.h"

int main(int argc, char* *argv){
    listitemptr k1 = NULL;
    int returnval;

    printf("Test case 1\n");

    printf("Asserting empty knapsack has size 0\n");
    returnval = KnapsackSize(&k1);
    assert(returnval == 0);

    KnapsackAdd(&k1, 1);
    printf("Asserting knapsack with one item (count 1) has size 1\n");
    returnval = KnapsackSize(&k1);
    assert(returnval == 1);

    printf("Test passed\n");
return 0;
}

1 Ответ

1 голос
/ 08 марта 2019

Нет ошибки сегментации, но есть ошибка подтверждения, а именно последняя в тестовом примере. Причина, по которой это происходит, заключается в том, что k1 равен NULL, что происходит потому, что в KnapsackAdd() первый тест if срабатывает, выделяет и инициализирует новый listitemptr. Однако затем он возвращается, и этот результат не обнаруживается в тестовом примере, а это означает, что k1 никогда не устанавливается на новый listitemptr. Это и утечка памяти, и логическая ошибка.

Чтобы исправить это, проще всего было бы сделать параметр knapsack указателем на указатель и затем установить его для недавно выделенного элемента в KnapsackAdd() для недавно выделенного элемента.

...