1

So, I'm doing a college assignment where basically what is needed is that you use a pointer that points to a dynamically allocated array of the correct size based on input from a data file. The problem is, I keep getting different errors when the program runs. The program compiles perfectly fine, but yet when it runs, it gives me this: "0xC0000005: Access violation reading location 0xFDFDFDFD."

Here is the code I'm using (do note that some of the code was written by my professor and before you ask, I attempted to contact him, and never got anything back from him):

Written by Professor

struct emprec   /*Employee record with two fields*/
{
    int id;
    float salary;
};
typedef emprec* emprecptr; /*Employee record pointer type*/
typedef emprecptr* indexarr; /* Pointer to a dynamic array of employee record pointers*/

Written by me

void readdata(indexarr& ptrs, int& size)
{
    size = 0;

    ptrs = nullptr;
    ptrs = new emprecptr[size];
    ifstream in;
    in.open("p1data.txt");
    if (!in) {
        cout << "Unable to open p1data.txt"; //if the file is not in the folder
        exit(1);
    }
    while (!in.eof()) {
        in >> ptrs[size]->id;        //putting to read line for id
        in.ignore();
        in >> ptrs[size]->salary;       //putting to read line for salary
        in.ignore();
        size = size + 1;

    }
    in.close();
};

  • 2
    `size = 0; ptrs = new emprecptr[size];`, so you're basically doing `new emprecptr[0]`, which is strange – ForceBru Sep 12 '20 at 20:54
  • [`while (!in.eof())`](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) This is one problem I see in your code. – πάντα ῥεῖ Sep 12 '20 at 20:54
  • Please edit your question to contain [mcve]. What is `emprecptr` ? What is `indexarr` ? – Slava Sep 12 '20 at 20:55
  • what would you suggest to use? – noobprogrammer26 Sep 12 '20 at 20:56
  • 1
    I would suggest to use `std::vector` obviously and to read following https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons – Slava Sep 12 '20 at 20:56
  • 2
    Why do they still teach C++ this way? std:: vector would be so much better. Try stepping through this in the debugger, check what the size is of the array and realize that you somehow have to reallocate it – JVApen Sep 12 '20 at 20:59
  • 2
    @JVApen because they do not really care what the end result is. – Slava Sep 12 '20 at 21:01
  • `new emprecptr[size]` creates an array of pointers, but nowhere do you make these pointers actually point somewhere. – Some programmer dude Sep 12 '20 at 21:05
  • 1
    As mentioned, use `std::vector` instead. And a vector of *object* (not pointers). I.e. `std::vector`. Any [decent book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) should have information about how to use it. – Some programmer dude Sep 12 '20 at 21:06
  • @Someprogrammerdude "new emprecptr[size] creates an array of pointer" actually it does not as `size` is 0, so even that is wrong – Slava Sep 12 '20 at 21:09
  • @noobprogrammer26 Is the function signature `void readdata(indexarr& ptrs, int& size)` also a requirement given by your professor, or did you choose to do it that way? – πάντα ῥεῖ Sep 12 '20 at 21:09
  • @πάντα ῥεῖ it is a requirement give by my professor. i did not choose it this way. – noobprogrammer26 Sep 12 '20 at 21:10
  • 1
    @noobprogrammer26 Well, that's unfortunate. It will make it hard to use a `std::vector` then. If I were you, I'd ditch that course, they're not teaching c++, no way. Looks like a waste of time for me. – πάντα ῥεῖ Sep 12 '20 at 21:14
  • @Slava Considering that [zero is a valid size](https://stackoverflow.com/a/1087066/440558), it's still an array of pointers being allocated. Although there are zero elements in it. On the other hand, two wrongs doesn't make a right. – Some programmer dude Sep 12 '20 at 21:21
  • let's say for the sake of argument, i change size to around 50. what would be considered the next step? – noobprogrammer26 Sep 12 '20 at 22:10
  • Unrelated: when you see a number or address like FDFDFDFD which is way to repetitious to be an accident, it's probably the program trying to tell you something [and you should look it up](https://en.wikipedia.org/wiki/Magic_number_(programming)#Debug_values). According to the link, the FDFDFDFD pattern is associated with accidentally accessing a guard region placed around a dynamic allocation to make it easier to detect buffer overflows. – user4581301 Sep 12 '20 at 22:21
  • You allocate that array of some size, if you know in advance reasonable max size then you use it. Otherwise you use arbitrary number and reallocate if you need more (copying old one over). Then you allocate data for each pointer when you read it. – Slava Sep 13 '20 at 00:34

2 Answers2

2
size = 0;

ptrs = nullptr;
ptrs = new emprecptr[size];

This sets size to 0, then creates an array, using new containing size values. Since size is 0 this creates an array containing exactly 0 values.

ptrs is a completely empty array (and the first assignment to a nullptr does not do anything useful, by the way).

    in >> ptrs[size]->id;        //putting to read line for id

The shown code then proceeds and attempts to put data into this array. But this array is completely empty. Its size is zero. It does not contain anything, so this doesn't go very far, and your program crashes.

And even if that wasn't the case, all that ptrs is, is an array of pointers. Even assuming that this array, itself is correctly allocated they are pointing to absolutely nothing whatsoever, until you actually new those pointers also.

    size = size + 1;

It looks like you believe that just because you incremented size here, and it was used earlier in the program to new an array, this must mean that this array will automatically grow by one value, too. This is not true. C++ does not work this way. Your C++ program does exactly what you tell it to do, one statement at a time. Your program news an array of a given size (zero size). That's what happens. The End. Nothing more will happen to that array, until you implement the code that does that.

Your homework assignment requires you to implement intelligent, sophisticated, memory management and fully understand how memory management works in C++. You need to implement moderately complicated logic that initially creates an array of some reasonable size, an array of ten or twenty pointers (pick some reasonable number yourself), then read one record at a time, new-ing each new record (apparently), and saving the newed pointer to it in this array. If the array becomes full, you will need to new a larger array, copy all the pointers from the smaller array to the larger array, delete the smaller array, and continue reading, until all records are read.

I am assuming that your assignment requires you to dynamically grow an array of indirect pointers. It is not quite clear, but it's possible that you simply need to dynamically grow the array of records themselves, instead. If so, this becomes slightly simpler, but the basic approach will be the same.

while (!in.eof()) {

Oh, and and this is also a nasty bug that you will need to fix, too.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • Thanks for pointing this out, @Slava. Stackoverflow allows answers to be edited, and you should not hesitate to correct these kinds of obvious fat fingers, yourself. – Sam Varshavchik Sep 13 '20 at 16:30
0

Looks like the memory that you're trying to reference is not allocated to the ptrs variable. It is beyond the size of memory that you've have allocated or it. Could you please check the size of variables allocated, that might give you some idea.