【问题标题】:More C Pointer Troubles更多 C 指针问题
【发布时间】:2019-02-13 13:34:06
【问题描述】:

我一直在研究数据结构和算法,遗憾的是用 C在这种情况下)包含不同类型的多个值。我可以创建一个列表并附加新节点,查看节点(pubs),然后删除(释放)它们。我的代码有多个问题,尽管我尽了最大努力,但仍无法解决它们。我知道我需要为使用 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;
}

【问题讨论】:

    标签: c pointers data-structures


    【解决方案1】:

    这里,

    newpub->name = name;
    

    您正在用 name 指针覆盖新分配的 newpub-&gt;name
    name 是字符串字面量的地址,你不能使用free

    出于某种原因,您在那个邮件上遗漏了strdup

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

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

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

    【讨论】:

      猜你喜欢
      • 2010-11-15
      • 2011-08-02
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多