【问题标题】:Initializing array of pointers初始化指针数组
【发布时间】:2011-10-01 05:26:45
【问题描述】:

我有一个 Deck 对象(卡片组),它是一个双端队列,实现为双向链表。我希望能够随意改组队列,但我的方式超出了我的范围。因此,我选择预先洗牌一个指向卡片的数组,并在事后将它们排入队列。问题是,我现在的代码似乎根本没有初始化指针。

void BuildDeck(Deck* deck) {
    Card** cards = new Card*[20];
    const size_t MAX_INTEGER_LENGTH = sizeof(int) * 4;
    char szPostfix[] = "_Card.bmp"; 

    for(int i = 1; i < 21; i++) {
        char path[MAX_INTEGER_LENGTH + sizeof(szPostfix) + 1];
        sprintf(path,"%d%s",i, szPostfix);
        cards[i-1] = new Card(i,path);
    }
    ShuffleArray(cards);
    for (int i = 0; i < 20; i++) {
        deck->PushTop(cards[i]);
    }
}

void Swap(Card* a, Card* b) {
    Card temp = *a;
    *a = *b;
    *b = temp;
}

void ShuffleArray(Card** cardArray) {
    srand(dbTimer());
    for (int i = 0; i < 20; i++)
        Swap(cardArray[i],cardArray[rand()%20]);
}

我认为我搞砸的地方是 card[i] = new Card(...) 行,但它在我看来是正确的。

任何建议将不胜感激。

免责声明:我知道我应该使用标准库来处理大部分这些东西,但我想先自学那些难的东西。这正是我学习的方式。

编辑:我修复了索引问题。现在我只是想弄清楚为什么有些图像现在没有绘制...:/感谢您的帮助!

【问题讨论】:

  • 对于固定大小的数组,您必须使用自动对象(即Card card[10][20];)。 new 应该仅在您确实需要动态分配时使用。
  • 您的swap 例程会比void swap(Card *&amp;a, Card *&amp;b) { Card *tmp = a; a = b; b = tmp; } 更好,以节省大量不必要的数据复制。
  • 那个交换修正修复它!谢谢!

标签: c++ arrays pointers shuffle


【解决方案1】:

你的代码有很多问题

  1. 您正在循环使用1 &lt;= i &lt;= 20,但对于包含 20 个元素的数组,索引来自 0 &lt;= index &lt;= 19。你需要使用cards[i-1] = new Card(i,path);

  2. 您正在分配指针数组cards,但您没有取消分配它(内存泄漏)。完成后使用delete[] cards; 释放它,或者使用Card *cards[20]; 使用基于堆栈的数组,而不是使用new 分配它。

  3. 您计算 MAX_INTEGER_LENGTH 的方式表明您并不真正了解 sizeof 的作用。

  4. 这就是卡片不会被洗牌的原因。您编写了一个交换两个指针的函数,但它交换的指针是函数的局部变量(参数),而不是数组的元素。一种解决方案是通过使用void Swap(Card *&amp; a, Card *&amp; b) 声明交换来将参数作为指针references 传递,另一种解决方案是将指针传递给指针(但由于双重间接,这将需要更复杂的实现语法并且还需要更改调用函数的方式)。

【讨论】:

  • 索引已修复。谢谢你。但是删除我的数组也会删除指针吗?我将这些指针传递给另一个集合;在其他集合完成之前我不想删除它们,对吗?
  • 泄露的是用于洗牌的指针数组(在BuildDeck 中命名为cards)。当您在 C++ 中删除指针数组时,指针所指向的对象不会自动删除。正如我在答案中所说,如果您只使用Card *cards[20]; 而不是使用new Card*[20] 在堆上分配它,那么代码会更简单。这样,当您退出构建函数时,临时数组会像其他自动变量一样自动释放。
【解决方案2】:

在第一个 for 循环中,您的起始索引为 0,而在第二个 for 循环中,起始索引为 0。这可能是问题所在。

【讨论】:

    【解决方案3】:

    您的代码:

     for(int i = 1; i < 21; i++) {
            char path[MAX_INTEGER_LENGTH + sizeof(szPostfix) + 1];
            sprintf(path,"%d%s",i, szPostfix);
            cards[i] = new Card(i,path);
        }
    

    这里的循环应该从0 开始到20 为:

     for(int i = 1 ; i < 21; i++) //incorrect - original code
    
     for(int i = 0 ; i < 20; i++) //correct - fix
    

    修复后,您可以在中使用i+1 而不是i

            sprintf(path,"%d%s",i+1, szPostfix);
            cards[i] = new Card(i+1,path);
    

    如果需要的话。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-28
      • 1970-01-01
      • 2016-12-09
      • 1970-01-01
      相关资源
      最近更新 更多