1

I am wanting to allocate storage for numbers from a file instead of storing them in a list and then finding the mean of the number. I have done this for a list below but i am struggling with the concept of doing this for a pointer. Any help is appreciated.

louiej15
  • 61
  • 7
  • Why would you want to switch from using a C++ container? There is no reason to dynamically allocate memory here. – crashmstr Feb 18 '15 at 15:58
  • it's for an assignment @crashmstr – louiej15 Feb 18 '15 at 16:00
  • Are you wanting to use malloc/free for real memory allocation, or new/delete with a C++ class? – user2867342 Feb 18 '15 at 16:01
  • @user2867342 new/delete, thanks in advance – louiej15 Feb 18 '15 at 16:04
  • 1
    @user2867342 "real memory allocation"? While `malloc` has uses in C++, `new` should be used in most cases for *any* dynamic memory allocations (which should be avoided when possible). – crashmstr Feb 18 '15 at 16:04
  • @crashmstr my main problem of understanding is with the file, i have managed to do this with an array. – louiej15 Feb 18 '15 at 16:10
  • 1
    I'm having a hard time believing that you could write the above code and not know how to do it with a pointer. – NathanOliver Feb 18 '15 at 16:13
  • What do you mean `i am struggling with the concept of doing this for a pointer` ? What exactly is your question? – Julian Feb 18 '15 at 16:13
  • @NathanOliver because i understand lists, i can't seem to allocate the file to a pointer, what i have tried is now in the question. – louiej15 Feb 18 '15 at 16:22
  • @AtlasC1 My question is how to allocate the file to a pointer, find the average then delete instead of using a list. What i have tried is now in the question. – louiej15 Feb 18 '15 at 16:23

2 Answers2

2

The main problem you need to overcome is to determine how much memory to allocate to hold all of your doubles. There a few ways you can do this:

The "easiest" way would be to do something naive, like reading the file once fully to get the number of doubles, then reading the file again to actually store the values in the the array:

std::ifstream in("numbers.txt");
unsigned int numElements = 0;

// Read the file once to determine how many elements it contains
double discard;
while (in >> discard) {
    numElements++;
}

// Go back to the beginning of file
in.clear() ;
in.seekg(0, std::ios::beg);

// Allocate array and read file contents into it
double* data = new double[numElements];
for ( int i = 0; i < numElements && is >> data[i]; i++ );

// Calculate the sum and average
double sum = 0;
for ( int i = 0; i < numElements; i++ ) {
    sum += data[i];
}

double average = sum / numElements;

// Free the dynanmically allocated memory
delete[] data;

It's pretty inefficient to read a file twice; and there are other ways to obtain the size beforehand. For example you could have a convention in your input file to include the number of elements as the first value before the data:

[infile.txt]
5 1.0 2.0 3.0 4.0 5.0

Now you can read the first value from the file, and you'll know that the rest of this file contains 5 doubles. Allocate your array with new (similar to above example), then continue to read the rest of the file into it.

Another alternative would be to do what std::vector does, which is begin by allocating enough memory in your array for 1 element. If you need to add another element, and the array is already full, re-allocate your array with twice as much memory and copy/move your old elements over to it. Repeat as necessary.

Julian
  • 1,688
  • 1
  • 12
  • 19
  • ah right, yeah i'm starting to grasp that more. One question, how would i open my file to then do this with the pointer as thats the bit i'm struggling with. – louiej15 Feb 18 '15 at 16:50
  • @louiej15 You already know that part :) You don't need to change anything there; `std::ifstream in("numbers.txt");` is all you need. I've updated my answer with this. – Julian Feb 18 '15 at 16:57
  • AtlasC1 has the answer, although for extra brownie points, you should always check that numElements is not zero before doing the divide. – user2867342 Feb 18 '15 at 17:08
0

Using C++ containers you need not worry about memory allocation. List elements are stored on the HEAP. This is essentially what you would be trying to achieve by using a pointer.

See List and list elements, where are stored?, When vectors are allocated, do they use memory on the heap or the stack? for more info.

If you still want to use pointers I would recommend using shared pointers http://en.cppreference.com/w/cpp/memory/shared_ptr, or another std smart pointer.

Community
  • 1
  • 1
Philip Wardlaw
  • 199
  • 2
  • 7
  • `Use a std::vector instead of a list` Don't just blindly use vectors. Each container type has its strengths and weaknesses, which depend on the context of the problem you're trying to solve. For example, the complexity of insertion and removal operations is linear in distance to the end of the vector *O(n)*, whereas it is constant in a list *O(1)*. – Julian Feb 18 '15 at 16:23
  • Good point. I checked it out and list elements are also on the heap. – Philip Wardlaw Feb 18 '15 at 18:04