更多C指针问题

时间:2019-02-13 13:34:07

标签: c pointers data-structures

我一直在研究数据结构和算法,可悲的是在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 :(得分:4)

在这里

newpub->name = name;

您正在用newpub->name指针覆盖新分配的name
name是字符串文字的地址,不允许您使用free

由于某种原因,您在该strdup上留了位。

此外,strdup会为您分配内存,因此当您覆盖这些指针时,您将泄漏所有malloc ed内存给成员。

仅使用strdupmalloc(但不要使用硬编码的大小),后跟strcpy

(并且不要强制转换malloc的结果。)