Больше проблем с указателем C - PullRequest
0 голосов
/ 13 февраля 2019

Я изучал структуры данных и алгоритмы, к сожалению, в C. Я отдельно реализовал двусвязный список, который содержит целые числа и работает нормально, но у меня много проблем, чтобы заставить его работать должным образом, когда узел (или пабв данном случае) содержит несколько значений разных типов.Я могу создать список и добавить новые узлы, просмотреть узлы (пабы), а затем удалить (бесплатно) их.У меня много проблем с кодом, и, несмотря на все мои усилия, я не могу их решить.Я знаю, что мне нужно освободить память для каждого атрибута, где я использовал malloc, но это приводит к сбою моей программы.Я снова уверен, что моя главная проблема - запутаться в том, как использовать указатели и указатели на указатели при переходе к функциям.Любая помощь будет принята с благодарностью !!

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

# define MAX_TOXICITY 30

typedef struct pub
{
  char *name;
  char *description;
  char *drink1;
  int drink1Strength;
  char *drink2;
  int drink2Strength;
  char *drink3;
  int drink3Strength;
  struct pub * prev ;
  struct pub * next ;
} pub;

typedef struct punter
{
  char playerName[20];
  int toxicity;
  struct pub * location;
} punter;

void append (struct pub** pubs, char name[], char description[], char drinka[], char drinkb[], char drinkc[], int aStrength, int bStrength, int cStrength)
{
  //printf("name: %s\tdescription: %s\n", name, description);
  struct pub *newpub, * iterator = * pubs;

  if (*pubs == NULL)
  {
    *pubs = (struct pub*)malloc(sizeof(struct pub));
    (*pubs)->prev = NULL;
    (*pubs)->next = NULL;

    (*pubs)->name = (char *)malloc((20) * sizeof(char));
    (*pubs)->description = (char *)malloc((100) * sizeof(char));
    (*pubs)->drink1 = (char *)malloc((20) * sizeof(char));
    (*pubs)->drink2 = (char *)malloc((20) * sizeof(char));
    (*pubs)->drink3 = (char *)malloc((20) * sizeof(char));
    (*pubs)->name = name;
    (*pubs)->description = strdup(description);
    (*pubs)->drink1 = strdup(drinka);
    (*pubs)->drink2 = strdup(drinkb);
    (*pubs)->drink3 = strdup(drinkc);
    (*pubs)->drink1Strength = aStrength;
    (*pubs)->drink2Strength = bStrength;
    (*pubs)->drink3Strength = cStrength;

  }
  else
  { 
    while (iterator->next != NULL)
      iterator = iterator->next;
    newpub = (struct pub *)malloc(sizeof(struct pub));
    newpub->next = NULL;
    newpub->prev = iterator;
    newpub->name = (char *)malloc((20) * sizeof(char));
    newpub->description = (char *)malloc((100) * sizeof(char));
    newpub->drink1 = (char *)malloc((20) * sizeof(char));
    newpub->drink2 = (char *)malloc((20) * sizeof(char));
    newpub->drink3 = (char *)malloc((20) * sizeof(char));
    iterator->next = newpub;
    newpub->name = name;
    newpub->description = strdup(description);
    newpub->drink1 = strdup(drinka);
    newpub->drink2 = strdup(drinkb);
    newpub->drink3 = strdup(drinkc);
    newpub->drink1Strength = aStrength;
    newpub->drink2Strength = aStrength;
    newpub->drink3Strength = aStrength;
  }
}

int count (struct pub * pubs)
{
  int count = 0;
  while ( pubs!= NULL)
  {
    pubs = pubs->next;
    count ++;
  }
  return count;
}

void display (struct pub *iterator)
{
  while (iterator != NULL)
  {
    //printf("Display Function Called:\n Name: %s\tDescription: %s\tprevious: %x\tnext: %x\n", 
    printf("Name: %s\tDescription: %s\nMenu: %s | %s | %s\n",
      iterator->name, iterator->description, iterator->drink1, iterator->drink2, iterator->drink3);
    iterator = iterator->next;
  }
}

void clear(struct pub **pubs)
{
  struct pub * iterator = *pubs;
  while(iterator->next != NULL)
  {
    iterator = iterator->next;
    //free(iterator->prev);
  }
  // now we are at the last pub, then clear in reverse
  while(iterator != NULL)
  {
    printf("Attempting to clear pub\n");
    iterator = iterator->prev;
   /* printf("Attempting to clear pub name\n");
    printf("iterator->next->name: %s\n", iterator->next->name);
    free(iterator->next->name);
    printf("Attempting to clear pub description\n");
    free(iterator->next->description);
    free(iterator->next->drink1);
    free(iterator->next->drink2);
    free(iterator->next->drink3);*/
    free(iterator);
    printf("Pub cleared\n");
  }
  free(iterator);
  printf("Pubcrawl Cleared\n");
}


int main ( void )
{
  pub **pubs;

  append(&pubs, "The Queens Cruciate Ligament", "Description Here", "Jungle Juice", "Johnson Ale", "Pubonic Acid", 2, 3, 5);
  append(&pubs, "The Nags Head", "Description Here", "Alco Cola", "McGuigans Real Ale", "Dark Hobo Rum", 5, 2, 3);
  append(&pubs, "The Kings Arm", "Description Here", "Whiskey Juice", "O'Johnson's Ginger Gin", "Bacon Beer", 2, 5, 3);
  append(&pubs, "The The Royal Joke", "Description Here", "Beverage of Truth", "Jackson Ale", "Ginger Ginger", 5, 3, 2);
  append(&pubs, "Flannagans", "Description Here", "Cola Flux", "McGuigans Fake Ale", "Light Hobo Rum", 3, 2, 5);
  append(&pubs, "McFlannagans", "Description Here", "Juicey Juice", "O'Johnson's Ginger Vodka", "Sausage Beer", 2, 5, 3);
  append(&pubs, "The Cow & Chicken", "Description Here", "Giant Juice", "Spencers Beer", "Generic Lager", 5, 2, 3);
  append(&pubs, "Bar Responsible", "Description Here", "Cola Cola", "McMcMcguigans Ale", "Leftover Beer", 0, 5, 5);
  append(&pubs, "The Dirty Donkey", "Description Here", "Tastey Johnson", "Sex on the Beach", "White Russian", 2, 2, 5);
  append(&pubs, "The Butchers Bear", "Description Here", "Water", "Dirty Water", "Dirtier Water", 3, 3, 5);
  display(pubs);



  clear(&pubs);

  return 0;
}

1 Ответ

0 голосов
/ 13 февраля 2019

Здесь

newpub->name = name;

вы перезаписываете только что выделенный newpub->name указателем name.
И name - это адрес строкового литерала, который выне разрешено free.

Вы по какой-то причине не указали strdup на этом.

Кроме того, strdup делает распределение для вас, так что вы просачиваетесьвся ваша malloc ed память для членов, когда вы перезаписываете эти указатели.

Используйте либо просто strdup, либо malloc (но не с жестко заданным размером), а затем strcpy.

(И не разыгрывайте результат malloc.)

...