LeCarloVC LeCarloVC - 24 days ago 8
Vb.net Question

Why is my program crashing before the end of the loop?

So the problem i am having is that my program seems to be crashing/not responding after the second last increment in the loop i have. My program is to ask the user the amount of students in the class, the max score on the test and then loop through the amount of students and the user gives the program the student name and their test score and then does other calculations within it.
The details of the score (name, marks, etc) are updated on a multi column list view at the end of each loop. The program works fine in the first increment of the loop but fails after that. Here's the code for the sub that does it:

Private Sub btnData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnData.Click

Dim NumStudent, HighestMark, LowestMark, ClassTotal, ClassMean, count As Integer
Dim HscScore As Decimal

Dim HscBand(5) As Integer
Dim Band1 As Integer = HscBand(0)
Dim Band2 As Integer = HscBand(1)
Dim Band3 As Integer = HscBand(2)
Dim Band4 As Integer = HscBand(3)
Dim Band5 As Integer = HscBand(4)
Dim Band6 As Integer = HscBand(5)

NumStudent = InputBox("Enter the number of students for this test")
NumStudent = NumStudent - 1

MaxScore = InputBox("Enter the maximum score for this test")


Dim student(NumStudent) As StudentHSC



For count = 0 To NumStudent
student(count).StudentName = InputBox("Enter the student's name")

student(count).StudentScore = InputBox("Enter the student's score for the test")
If student(count).StudentScore > MaxScore Then
MessageBox.Show("You can not enter a number higher than the max score, please enter it again")
student(count).StudentScore = InputBox("Enter the student's score for the test")
End If

HscScore = student(count).StudentScore / MaxScore * 100
student(count).HscMark = Format(HscScore, "0.00")

If student(count).HscMark < 50 Then
student(count).HscRank = 1
HscBand(0) = HscBand(0) + 1
lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore, student(count).HscMark, student(count).HscRank}))

ElseIf student(count).HscMark = 50 And student(count).HscMark < 60 Then
student(count).HscRank = 2
HscBand(1) = HscBand(1) + 1
lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore, student(count).HscMark, student(count).HscRank}))

ElseIf student(count).HscMark = 60 And student(count).HscMark < 70 Then
student(count).HscRank = 3
HscBand(2) = HscBand(2) + 1
lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore, student(count).HscMark, student(count).HscRank}))

ElseIf student(count).HscMark = 70 And student(count).HscMark < 80 Then
student(count).HscRank = 4
HscBand(3) = HscBand(3) + 1
lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore, student(count).HscMark, student(count).HscRank}))

ElseIf student(count).HscMark = 80 And student(count).HscMark < 90 Then
student(count).HscRank = 5
HscBand(4) = HscBand(4) + 1
lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore, student(count).HscMark, student(count).HscRank}))

ElseIf student(count).HscMark = 90 And student(count).HscMark < 101 Then
student(count).HscRank = 6
HscBand(5) = HscBand(5) + 1
lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore, student(count).HscMark, student(count).HscRank}))

End If







Next


I've already had too many problems with this program, all have been solved except for this one. I have a feeling that it has something to do with NumStudent variable...

Also StudentHSC is a public function.

Edit: Here's the public variables and structure that i have set and the listview format:

Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lstStuData.View = View.Details
lstStuData.Columns.Add("Student Name", 100, HorizontalAlignment.Left)
lstStuData.Columns.Add("Score", 60, HorizontalAlignment.Left)
lstStuData.Columns.Add("Percentage", 70, HorizontalAlignment.Left)
lstStuData.Columns.Add("Band", 60, HorizontalAlignment.Left)


End Sub

Public MaxScore As Integer
Public student As String

Public Structure StudentHSC
Dim StudentName As String
Dim StudentScore As Integer
Dim HscRank As Integer
Dim HscMark As Integer
End Structure

Answer

I would encourage you to code with an Option Strict On declaration so as not to rely on implicit casting from one type to another.

The answer to your question is that you have declared an array of StudentHSC objects with (NumStudents + 1) elements. StudentHSC is a reference type and therefore each element of the array is a pointer to an object. Until an object is created on the heap by use of the New keyword, each pointer is not pointing to any object or is pointing to "Nothing". Therefore if you try to assign a value to a property of an element (e.g. StudentName), you will get a "null reference exception". To solve the problem, insert the following line at the top of the For loop:

student(count) = New StudentHSC

You haven't shown the StudentHSC class so I am assuming it has a constructor that takes no parameters.

So the start of the For loop should look like this:

For count = 0 To NumStudent
    student(count) = New StudentHSC
    student(count).StudentName = InputBox("Enter the student's name")

Also you have a lot of unused or redundant variables and you should be validating the user entries of the input boxes to ensure that numerical values have been provided.

EDIT:

The If clause should look like this:

If student(count).HscMark < 50 Then
    student(count).HscRank = 1
    HscBand(0) = HscBand(0) + 1
    lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore.ToString, student(count).HscMark.ToString, student(count).HscRank.ToString}))
ElseIf student(count).HscMark >= 50 AndAlso student(count).HscMark < 60 Then
    student(count).HscRank = 2
    HscBand(1) = HscBand(1) + 1
    lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore.ToString, student(count).HscMark.ToString, student(count).HscRank.ToString}))
ElseIf student(count).HscMark >= 60 AndAlso student(count).HscMark < 70 Then
    student(count).HscRank = 3
    HscBand(2) = HscBand(2) + 1
    lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore.ToString, student(count).HscMark.ToString, student(count).HscRank.ToString}))
ElseIf student(count).HscMark >= 70 AndAlso student(count).HscMark < 80 Then
    student(count).HscRank = 4
    HscBand(3) = HscBand(3) + 1
    lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore.ToString, student(count).HscMark.ToString, student(count).HscRank.ToString}))
ElseIf student(count).HscMark >= 80 AndAlso student(count).HscMark < 90 Then
    student(count).HscRank = 5
    HscBand(4) = HscBand(4) + 1
    lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore.ToString, student(count).HscMark.ToString, student(count).HscRank.ToString}))
ElseIf student(count).HscMark >= 90 AndAlso student(count).HscMark <= 100 Then
    student(count).HscRank = 6
    HscBand(5) = HscBand(5) + 1
    lstStuData.Items.Add(New ListViewItem(New String() {student(count).StudentName, student(count).StudentScore.ToString, student(count).HscMark.ToString, student(count).HscRank.ToString}))
End If
Comments