【问题标题】:C Program pointer being realloc'd was not allocated未分配被重新分配的 C 程序指针
【发布时间】:2019-02-14 21:53:32
【问题描述】:

我尝试通过某些条件创建一个数组的两个子数组,并使用 realloc 来增加指针空间。 但是,未分配此代码:显示正在重新分配的指针。 总共有 5 项,第 4 项失败。我真的很困惑为什么它可以在前 3 个项目上成功。

void sortHand(Hand *hand, Suit trump) {
  int length = NUM_CARDS_IN_HAND - 1;
  Card *cards = getAllCardsFromHand(hand, length);
  Card *trumpCards = (Card*)malloc(sizeof(Card));
  Card *otherCards = (Card*)malloc(sizeof(Card));
  int trumpCount = 1, otherCount = 1;
  for (int i = 0; i <= length ; i++) {
    Card curtCard = cards[i];
    if (curtCard.suit == trump){
      trumpCount = addCardsBySuit(trumpCards, curtCard, trumpCount);
      printf("trumpCount %d\n", trumpCount);
      continue;
    }
      otherCount = addCardsBySuit(otherCards, curtCard, otherCount);
      printf("otherCount%d\n", otherCount);
  }
  if (trumpCards == NULL) {
    printf("Trump is zero. Other is %d.", (otherCount + 1));
    addAllCardsTohand(otherCards, hand, otherCount);
    return;
  }
  if (otherCards == NULL){
    printf("Other is zero. Trump is %d.", (trumpCount + 1));
    addAllCardsTohand(trumpCards, hand, trumpCount);
    return;
  }
  printf("Trump is %d. Other is %d.", (trumpCount + 1), (otherCount + 1));
  addAllCardsTohand(trumpCards, hand, trumpCount);
  addAllCardsTohand(otherCards, hand, otherCount);
}

我认为问题出在这个函数上。

int addCardsBySuit(Card *trumpCards, Card card, int trumpCount) {
  printf("addCardsBySuit\n");
  Card *moreCards = (Card*)realloc(trumpCards, trumpCount * sizeof(Card));
  trumpCards = moreCards;
  trumpCards[trumpCount] = card;
  trumpCount++;
  return trumpCount;
}

这是我的测试代码和输出。

void test_sort_hand() {
  start_test("sort_hand");
  Hand *hand = createHand();
  Card card1 = {NINE, HEARTS, -1};
  addCardToHand(&card1, hand);
  Card card2 = {JACK, HEARTS, -1};
  addCardToHand(&card2, hand);
  Card card3 = {ACE, HEARTS, -1};
  addCardToHand(&card3, hand);;
  Card card4 = {QUEEN, HEARTS, -1};
  addCardToHand(&card4, hand);;
  Card card5 = {TEN, SPADES, -1};
  addCardToHand(&card5, hand);
  printHand(hand);
  sortHand(hand, HEARTS);
  printHand(hand);
  end_test();
}

0: Ten_Spades
1: Queen_Hearts
2: Ace_Hearts
3: Jack_Hearts
4: Nine_Hearts
addCardsBySuit
otherCount2
addCardsBySuit
trumpCount 2
addCardsBySuit
trumpCount 3
addCardsBySuit
test(5155,0x11820d5c0) malloc: *** error for object 0x7fd811402b50: pointer being realloc'd was not allocated
test(5155,0x11820d5c0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort trap: 6

【问题讨论】:

  • 一般来说,如果你分配一个大小为 N 的对象,然后尝试引用元素 N,你就是越界了。也就是说,如果数组的大小为 N,则引用 array[N] 是错误的。如果分配的指针大小为trumpCount * sizeof(Card),则可以通过索引0trumpCount -1 将其作为数组访问
  • 您的问题是 realloc 的结果,它对 addCardsBySuit 的调用者和下一个 realloc 不可见下一个循环无效,看我的回答

标签: c pointers realloc


【解决方案1】:

int addCardsBySuit(Card *trumpCards, Card card, int trumpCount) {
  printf("addCardsBySuit\n");
  Card *moreCards = (Card*)realloc(trumpCards, trumpCount * sizeof(Card));
  trumpCards = moreCards;
  trumpCards[trumpCount] = card;
  trumpCount++;
  return trumpCount;
}

addCardsBySuit 中,trumpCards 的值没有改变,因此下次您将调用 addCardsBySuit 并尝试 realloc 你将再次对旧值执行不再有效的操作,而不是 realloc

的先前结果

你可以改变

int addCardsBySuit(Card **trumpCards, Card card, int trumpCount) {
  printf("addCardsBySuit\n");
  Card *moreCards = (Card*)realloc(*trumpCards, trumpCount * sizeof(Card));
  *trumpCards = moreCards;
  (*trumpCards)[trumpCount] = card;
  trumpCount++;
  return trumpCount;
}

当然要更改调用以提供指针所在的地址:

void sortHand(Hand *hand, Suit trump) {
  int length = NUM_CARDS_IN_HAND - 1;
  Card *cards = getAllCardsFromHand(hand, length);
  Card *trumpCards = (Card*)malloc(sizeof(Card));
  Card *otherCards = (Card*)malloc(sizeof(Card));
  int trumpCount = 1, otherCount = 1;
  for (int i = 0; i <= length ; i++) {
    Card curtCard = cards[i];
    if (curtCard.suit == trump){
      trumpCount = addCardsBySuit(&trumpCards, curtCard, trumpCount);
      printf("trumpCount %d\n", trumpCount);
      continue;
    }
      otherCount = addCardsBySuit(&otherCards, curtCard, otherCount);
      printf("otherCount%d\n", otherCount);
  }
...

【讨论】:

  • 成功了!教训应该是,如果我想更改函数外部的指针,我需要使用指针的指针来完成。我说的对吗?
  • @AlexFan 无论变量的类型如何,如果您想在调用者级别更改值,您可以给它一个指针(所以如果 var 的类型是指针,则为双指针) 参数是输入-输出参数而不仅仅是输入参数,另一种解决方案是返回新值以允许调用者记住新值,但这里你已经返回了一个值
  • @AlexFan 所以你也可以更改为 addCardsBySuit(Card **trumpCards, Card card, int *trumpCount) 其中 trumpCount 也是一个输入输出参数,调用者不必执行 trumpCount = addCardsBySuit(&amp;trumpCards, curtCard, trumpCount); 但 @987654326 @,当然还有在 addCardsBySuit 中取消对 trumpCount 的引用,就像 trumpCards 所必需的那样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多