C++ 查找对象数组中最后使用的元素

C++ 查找对象数组中最后使用的元素,c++,arrays,C++,Arrays,我有一个Student对象数组。我将数组长度设置为100,但其中没有100个有效的Student对象。我希望能够遍历数组并获取所有有效的Student对象,然后在到达没有Student对象的数组单元格时停止 我尝试将NULL放在最后一个学生之后的数组单元格中,然后检查if(queriedStudents[I])以及if(queriedStudents[I]!=NULL),但这两种方法都不适用于我 查找阵列中已使用部分的结尾的最佳方法是什么 Student *Welcome::queryStude

我有一个
Student
对象数组。我将数组长度设置为100,但其中没有100个有效的
Student
对象。我希望能够遍历数组并获取所有有效的
Student
对象,然后在到达没有Student对象的数组单元格时停止

我尝试将
NULL
放在最后一个学生之后的数组单元格中,然后检查
if(queriedStudents[I])
以及
if(queriedStudents[I]!=NULL)
,但这两种方法都不适用于我

查找阵列中已使用部分的结尾的最佳方法是什么

Student *Welcome::queryStudents(int *queries) {
    int query = 0;
    Student *matchedStudents[100];
    int matchedPos = 0;
    while (queries[query] > 0) {
        for (int i = 0; i < numStudents; i++) {
            if (allStudents[i]->id == queries[query]) {
                matchedStudents[matchedPos] = allStudents[i];
                matchedPos++;
            }
        }

        query++;
    }
    matchedStudents[matchedPos] = NULL;

    return *matchedStudents;
}

你有更大的问题。在函数
queryStudents
的堆栈上声明数组
matchedStudents
。当控件传递出该函数时,数组将传递出作用域。如果您稍后试图使用它(通过它返回的指针,它是数组的第一个元素),那么您将弄乱释放的内存,这几乎肯定会导致未定义的行为。这就好像你正在参观一所房子,自从你上次去那里以来,它已经改变了主人;没有人知道发生了什么变化,如果你闭着眼睛四处游荡,你可能会遇到麻烦

您可以在堆上声明数组:

Student **Welcome::queryStudents(int *queries) {
  Student **matchedStudents = new *Student[100];
    ...
  return matchedStudents;
}
或通过引用传递:

void Welcome::queryStudents(int *queries, Student **&matchedStudents) {
    ...
}

无论哪种方式,您都可以解决如何指示有效指针结束的问题。您的方法看起来是可行的,但请记住@JerryCoffin已经指出,
std::vector
是可用的。数组是个麻烦,STL容器(比如
vector
)就是为了帮您处理这些肮脏的细节而设计的。如今,除了教学法之外,使用阵列几乎没有任何用途;在理解概念之前,先使用它们,然后使用基于它们的更高级容器。

您遇到了更大的问题。在函数
queryStudents
的堆栈上声明数组
matchedStudents
。当控件传递出该函数时,数组将传递出作用域。如果您稍后试图使用它(通过它返回的指针,它是数组的第一个元素),那么您将弄乱释放的内存,这几乎肯定会导致未定义的行为。这就好像你正在参观一所房子,自从你上次去那里以来,它已经改变了主人;没有人知道发生了什么变化,如果你闭着眼睛四处游荡,你可能会遇到麻烦

您可以在堆上声明数组:

Student **Welcome::queryStudents(int *queries) {
  Student **matchedStudents = new *Student[100];
    ...
  return matchedStudents;
}
或通过引用传递:

void Welcome::queryStudents(int *queries, Student **&matchedStudents) {
    ...
}

无论哪种方式,您都可以解决如何指示有效指针结束的问题。您的方法看起来是可行的,但请记住@JerryCoffin已经指出,
std::vector
是可用的。数组是个麻烦,STL容器(比如
vector
)就是为了帮您处理这些肮脏的细节而设计的。如今,除了教学法之外,使用阵列几乎没有任何用途;在理解这些概念之前,先使用它们,然后使用基于它们的更高级容器。

如果可能,使用
std::vector
而不是数组--它将跟踪它包含的对象数。如果数组包含指针,则只要在开始向数组添加指针之前用NULL初始化数组,使用NULL描述的方法就可以工作。这将使您不得不手动处理每个项目的新建/删除。正如Jerry所说,vector是避免这种情况的一个好选择,它只存储您实际使用的内容。如果出于任何原因不能使用vector,另一种选择是向Student对象添加一个
valid
成员,该成员默认初始化为false,只有在对象中存在真实数据时才设置为true。@RetiredInja:注释不错,回答得更好。发帖!如果可能,请使用
std::vector
而不是数组--它将跟踪它包含的对象数。如果数组包含指针,则只要在开始向数组添加指针之前使用NULL初始化数组,使用NULL描述的内容就可以工作。这将使您不得不手动处理每个项目的新建/删除。正如Jerry所说,vector是避免这种情况的一个好选择,它只存储您实际使用的内容。如果出于任何原因不能使用vector,另一种选择是向Student对象添加一个
valid
成员,该成员默认初始化为false,只有在对象中存在真实数据时才设置为true。@RetiredInja:注释不错,回答得更好。发帖!这正是我所处的位置;这是我这学期第一次的作业,我最大的问题是从java和AS3切换到C++。一旦我了解了这些概念,我就会继续前进。这正是我所处的位置;这是我这学期第一次的作业,我最大的问题是从java和AS3切换到C++。一旦我了解了这些概念,我就会继续前进。