Function crashing on specific data set

I'm trying to find the mode of an data set, and am using 2 different data sets. One set definitely has a mode in it (this set runs with no problems)
The other set crashes when it runs through this function. I think I've isolated that this happens in my first for loop, however I'm not sure why.
Does anyone have any idea why?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
ModeData findMode(int arr[], int range, int numElem)
{
   ModeData modeData = { 0, 0 };
   int * mode = nullptr;
   mode = new int[range + 1]; //creates a counting array to be incremented for each time a number appears in arr[]

   //ensures all elements are 0 before being used as a counter
   for (int i = 0; i < numElem; ++i)
      mode[i] = 0;

   //counts and stores how many times each number appears
   for (int i = 0; i < numElem; ++i)
      mode[arr[i]] += 1;

   //finds the actual mode and frequency and stores them in modeData
   for (int i = 0; i < numElem; ++i)
      if (mode[i] > modeData.frequency)
      {
         modeData.frequency = mode[i];
         modeData.mode = i;
      }//end if
   delete[] mode;

   return modeData;

}//end findMode 
What is the difference between range and numElem? You created an array with the size of range + 1, so if numElem is larger than range + 1 you are accessing your array out of bounds.

Why are you using an array instead of a std::vector?

It would also help if you posted a small complete program that illustrates the problem, be sure you also post the contents of your input files.

Sorry for not clarifying with those variables, range is the largest number in the array and numElem is the number of elements in the array.

I'm doing this for a college class and my instructor prefers arrays over vectors.

The input files are ~700 numbers each so I wasn't sure if that would have been a data overload, I'll go ahead and post my entire source code though.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <iostream>
#include <fstream>

using namespace std;

struct FileData
{
   int * dataArray; // pointer to dynamic data array
   int count; // total number of elements in the file
   int maxElem = 0; // largest element in the file
};
struct ModeData
{
   int mode; // element that is mode
   int frequency; // frequency of the mode
};


//Prototypes
FileData readDataFromFile(ifstream & inFile, int size);
ModeData findMode(int arr[], int range, int numElem);
void displayMode(int mode, int frequency);


void main()
{
   ifstream file;
   const int SIZE = 700; // size of dataArray
   FileData fileData; 
   ModeData modeData;
   fileData.dataArray = new int[SIZE];
   
   file.open("RandomModeOneMode.txt"); // opens file with one mode
   //file.open("RandomModeNoModes.txt"); // opens file with no mode

   fileData = readDataFromFile(file, SIZE);


   modeData = findMode(fileData.dataArray, fileData.count, fileData.maxElem);


   displayMode(modeData.mode, modeData.frequency);
   delete[] fileData.dataArray;

   system("Pause");

}//end main


/**************************************************************************************************************************
readDataFromFile                                                                                                          *
ifstream(to be read from), int(size of dynamic array)                                                                     *
Gets data from input file and stores it in a dynamic array. Also counts the number of elements and finds the max element  *
**************************************************************************************************************************/
FileData readDataFromFile(ifstream & inFile, int size)
{
   FileData tempfileData;
   tempfileData.dataArray = new int[size]; //dynamic array to hold elements from file

   if (!inFile)
      cout << "File failed to open properly.\n";
   else
   {
      //cycles through counting elements in array, storing them all in tempfiledata, and finding the max element
      for (tempfileData.count = 0; tempfileData.count < size && inFile >> tempfileData.dataArray[tempfileData.count]; ++(tempfileData.count))
      {
         if (tempfileData.dataArray[tempfileData.count] > tempfileData.maxElem)
            tempfileData.maxElem = tempfileData.dataArray[tempfileData.count]; // stores the new maxelem if it is greater than the previous
      }//end for 
   }//end else



   return tempfileData;

}//end readDataFromFile


/**************************************************************************************************************
findMode                                                                                                      *
int[](number set to find mode of), int(range of numbers being looked at), int(size of array being looked at)  *
Finds mode of the argument array and returns the mode and frequency                                           *
**************************************************************************************************************/
ModeData findMode(int arr[], int range, int numElem)
{
   ModeData modeData = { 0, 0 };
   int * mode = nullptr;
   mode = new int[range + 1]; //creates a counting array to be incremented for each time a number appears in arr[]

   //ensures all elements are 0 before being used as a counter
   for (int i = 0; i < numElem; ++i)
      mode[i] = 0;

   //counts and stores how many times each number appears
   for (int i = 0; i < numElem; ++i)
      mode[arr[i]] += 1;

   //finds the actual mode and frequency and stores them in modeData
   for (int i = 0; i < numElem; ++i)
      if (mode[i] > modeData.frequency)
      {
         modeData.frequency = mode[i];
         modeData.mode = i;
      }//end if
   delete[] mode;

   return modeData;

}//end findMode


/**********************************************************************************
displayMode                                                                       *
int(mode of a data set), int(frequency the mode appears)                          *
Displays the mode and frequency of a data set, or states that one does not exist  *
**********************************************************************************/
void displayMode(int mode, int frequency)
{
   if (frequency != 1)
   {
      cout << "The mode of this data set is: " << mode << endl;
      cout << "The frequency of the mode is: " << frequency << endl;
   }//end if
   else
      cout << "There is no mode in this data set.\n";

}//end displayMode 


Hi,

The main problem I see is that you have used one file variable to open 2 files

33
34
file.open("RandomModeOneMode.txt"); // opens file with one mode
   //file.open("RandomModeNoModes.txt"); // opens file with no mode 


either use 2 file variable (like file1 & file2)

or use different scopes(not recommended)

or use clear() and close() functions, which I think will make code more lengthy...


Hope it helps
Last edited on
The reason for the same variable is just so I can have a test data set that does not have a mode in it. Whenever I use the other, I will just swap the comments out.
One of the first things I notice is you have a memory leak.

1
2
3
4
5
6
...
   FileData fileData; 
   ModeData modeData;
   fileData.dataArray = new int[SIZE];
...
   fileData = readDataFromFile(file, SIZE); /// Memory leak here.  


You allocate memory for your pointer in main. Then you function returns a different structure so you loose the pointer to this allocated memory.

Another thing I see is that you appear to be using uninitialized variables in the read function.

I've just removed that
fileData.dataArray = new int [SIZE];
line.
The program still runs fine when there is a mode, like in the first file, but I am getting thrown this exception with the second file:
Unhandled exception at 0x011180A1 in CS1337.exe: 0xC0000005: Access violation writing location 0x00EE1000.
Have you tried running the program with your debugger? The debugger should be able to tell you exactly where it encounters the problem.

What have you done about the uninitialized variables in your read function? Remember your structure variables are not initialized to any value when you declare a class, unless you use a constructor to initialize them.

Without seeing your input file that is causing the problem I can only guess as to the actual problem, and I'm a horrible guesser.


I pulled up the debugger and its telling me the problem is at
mode[i] = 0;
in findMode.
Which variables do you see that are uninitialized?

These numbers are what cause the program to crash, each number has its own line in the file. Sorry about the long wall, but I'm not sure how to format it better:
41
467
334
500
1169
1724
1478
1358
962
464
1705
145
1281
827
1961
491
995
1942
1436
391
604
1902
153
292
382
1421
716
1718
1895
1447
1726
771
1538
1869
1912
1667
299
1035
1894
703
1811
1322
333
1673
664
1141
1711
253
868
1547
1644
662
757
37
859
723
1741
1529
778
316
190
1842
288
106
1040
942
1264
648
1446
1805
1890
729
370
1350
1006
1101
393
1548
1629
623
84
1954
756
1840
966
1376
1931
308
944
439
626
1323
1537
118
82
929
541
833
1115
639
1658
704
1930
1977
306
386
1021
745
924
1072
270
1829
777
1573
1097
512
1986
1290
1161
636
355
767
1655
1574
31
52
1150
941
1966
1430
1107
191
7
1337
1457
287
1753
383
945
909
209
1758
221
588
422
946
1506
1030
413
1168
900
591
762
1410
359
1624
537
483
1595
1602
350
291
836
1374
1020
596
21
1348
1199
1668
484
281
734
53
1999
418
1938
1788
127
1728
893
1807
421
310
617
813
1514
309
1616
935
1451
600
1249
519
1556
798
303
224
1008
1844
609
989
702
1195
485
1093
343
523
1587
1314
1503
1448
1200
1458
618
580
1796
1589
9
1157
472
1622
538
38
179
1657
1958
1815
888
1156
1511
202
634
272
55
328
646
362
886
875
433
142
1416
1881
1998
322
651
1699
1557
476
1892
389
1075
712
510
1003
869
1861
688
1401
1789
1255
423
1002
585
182
285
1088
1426
1757
1832
932
169
154
1721
1189
1976
1329
368
692
1425
555
1434
549
1441
1512
60
139
279
1996
687
529
1437
1866
949
193
1297
416
286
105
488
282
455
1734
114
1701
1316
671
1786
263
313
1185
912
808
1756
321
1558
1646
1982
481
144
1196
222
1129
161
1535
450
1173
466
44
1659
1253
24
1510
649
1186
474
22
168
18
787
1905
1391
1625
477
414
1824
1334
1874
372
159
1833
70
1487
297
1518
177
1773
1763
668
1192
1985
1102
480
1213
1627
802
99
527
625
1543
1924
1023
1972
1061
181
1432
1505
1593
725
1031
492
1222
1286
1064
1900
1187
360
974
1170
235
1760
896
667
1285
550
140
1694
695
19
125
576
658
302
1371
678
593
1851
1484
1018
1119
1152
800
87
1060
1926
1010
170
315
1576
227
43
758
1164
1109
1882
1086
1565
1577
1928
1423
520
902
123
1737
1261
195
525
The size of the mode array in findMode() is not equal to numElem.

For the data provided you pass in fileData.maxElem to numElem = 1999.

You pass fileData.count to range = 438 => size of mode array = 439.

mode[i] accesses beyond array bounds for 438 < i < 1999.

To fix the code replace range in mode = new int[range + 1] with numElem and replace numElem in the second for loop with range.
Last edited on
You are a wonderful person and I like you. Thanks very much!
Both files are working properly now.
Topic archived. No new replies allowed.