0

I'm in the process of teaching myself C++ and am currently learning about dynamically allocating memory. Here's the code that I'm currently working with:

#include <iostream>

using namespace std;

int *memAdd(int* dyn_Point, int *lenPoint){
   int *new_Dyn_Point = new int[*lenPoint * 2];
   *lenPoint = *lenPoint * 2;
   for(int i = 0; i < *lenPoint; i++){
       new_Dyn_Point[i] = dyn_Point[i];
   }

   delete lenPoint;
   delete[] dyn_Point;
   return new_Dyn_Point;

}

int main(){

   int len = 2;
   int *lenPoint = &len;
   int current = 0;
   int val;
   int *dyn_Point = new int[len];


   cout << "Input a value for point 1: ";
   cin >> val;
   dyn_Point[current] = val;


   while(val > 0){
      current++;

      cout << "Input a value for point " << current+1 <<" (0 to exit): ";
      cin >> val;

      if(current+1 == len){
         *dyn_Point = *memAdd(dyn_Point, lenPoint);
         cout << len;
      }

      dyn_Point[current] = val;


   }

   for(int i = 0; i < len; i++){
     cout << &dyn_Point[i] << "\n";
     cout << dyn_Point[i] << "\n\n";

 }
 delete[] dyn_Point;

}

My Question: When adding more memory does it have to increment by a certain value?

Whenever I start with a value in my "len" variable that's not 2 my program will crash either as soon as I try and allocate more memory or after more memory has been allocated and even more has to be added a second time.

Is this how it's supposed to be or am I missing something entirely here?

  • THe issue might be in: while(val > 0){ current++; That first ++ gives you 1 for current, then you go to current+1 in your check in the if-statement to add the memory, so only if len==2 you add memory. – Norbert Apr 21 '15 at 01:49
  • You're copying twice as much data as you should. That's likely to cause a crash. – Mike Seymour Apr 21 '15 at 01:50
  • 1
    Also `delete lenPoint` is wrong, since it doesn't point to a dynamic object. – Mike Seymour Apr 21 '15 at 01:52
  • @NorbertvanNobelen I don't believe there would be an issue in that area. The "current++" at the beginning of the loop increments it to 1 since "dyn_Point[0]" is filled just before the loop starts. As for the "current+1" in my if statement, that was left over from me attempting to solve the issue but has no real effect on anything I change – FutureWizard Apr 21 '15 at 01:59
  • @MikeSeymour Where am I copying twice as much data as I should, could you be a little more clear on that? Also I just got a little overzealous with deleting stuff since I'm still pretty new to pointers and dynamic objects, thanks for pointing that out. – FutureWizard Apr 21 '15 at 02:02
  • @FutureWizard: In the loop that copies the data in `memAdd`. It goes up to the new value of `*lenPoint`, which is twice the size of the old array. – Mike Seymour Apr 21 '15 at 02:03
  • @MikeSeymour Well the whole point of the memAdd function is to double the amount of memory that dyn_Point holds. Which still isn't the issue seeing as it easily doubles from 2 to 4 to 8 and so on and continues running but when I start with a value like 10 it will double to 20 then once the 20 spaces are full, instead of doubling to 40 the program crashes. – FutureWizard Apr 21 '15 at 02:10
  • @FutureWizard: Indeed, it's supposed to double the amount. But it's only supposed to copy the existing data across, of which there is only the old amount, or half the new amount. You're trying to copy the new amount across, but there isn't that much in the old array. The loop goes off the end of the old array into unallocated memory, which might well be the cause of the crash. – Mike Seymour Apr 21 '15 at 09:21

2 Answers2

0

Your while loop need a break

while() {

    //do your steps
    break;
}

In function memAdd following changes required :

// *lenPoint = *lenPoint * 2; 

// above line need to be commented else it will trouble the loop condition by causing over flow:

    for(int i = 0; i < (*lenPoint-1); i++){

// for loop is corrected to resolve the over flow

Below delete is unnecessary since you didn't allocate memory using this variable

// delete lenPoint;

For your question: When adding more memory does it have to increment by a certain value?

There is no hard and hard fast rule on this regard. std::vector<> double its size( memory allocation) whenever it is needed more memory. It is slightly different than your approach. You are doubling memory before reaching the allocated upper limit.

**Edit**

Compiled full code as OPs request

#include <iostream>

using namespace std;

int *memAdd(int* dyn_Point, int *lenPoint){
   int *new_Dyn_Point = new int[*lenPoint * 2];
  // *lenPoint = *lenPoint * 2;
   for(int i = 0; i < (*lenPoint-1); i++){
       new_Dyn_Point[i] = dyn_Point[i];
   }

   //delete lenPoint;
   delete[] dyn_Point;
   return new_Dyn_Point;

}

int main(){

   int len = 2;
   int *lenPoint = &len;
   int current = 0;
   int val;
   int *dyn_Point = new int[len];


   cout << "Input a value for point 1: ";
   cin >> val;
   dyn_Point[current] = val;


   while(val > 0){
      current++;

      cout << "Input a value for point " << current+1 <<" (0 to exit): ";
      cin >> val;

      if(current+1 == len){
         *dyn_Point = *memAdd(dyn_Point, lenPoint);
         cout << len<<"\n";
      }

      dyn_Point[current] = val;
     break;

   }

   for(int i = 0; i < len; i++){
     cout << dyn_Point[i] << "\n";
     cout << &dyn_Point[i] << "\n\n";

 }
 delete[] dyn_Point;

}
Steephen
  • 14,645
  • 7
  • 40
  • 47
  • Putting `break;` in my while loop would just end it after the first iteration wouldn't it? That wouldn't really do anything to help me. Commenting out `*lenPoint = *lenPoint * 2; ` would prevent me from having a variable to use in order to control how long to run certain loops for since `for(int i = 0; i < 1; i++)` would only print out the value of `dyn_Point[0]` then the loop would end. – FutureWizard Apr 21 '15 at 02:22
  • @FutureWizard you can decide the condition to break the while loop else it will end as an infinite loop. You have to comment this line *lenPoint = *lenPoint * 2; but I corrected the for loop condition in answer instead hard coding. That variable is available even if we comment that line. loop should end after printing first variable, becuase there is only one value inserted so far in that allocated memory – Steephen Apr 21 '15 at 02:26
  • Have you tried compiling this code yourself? It still isn't working, as expected, because without `*lenPoint = *lenPoint * 2;` then `len` is never set to anything more than 2 making `for(int i = 0; i < (*lenPoint-1);` exactly the same as `for(int i = 0; i < 1;` There's also no need to set a break condition because the loop exits upon the user typing 0. – FutureWizard Apr 21 '15 at 02:37
0

"My Question: When adding more memory does it have to increment by a certain value?"

Of course you have to manage your memory allocations using a design like this.

In particular you should obey the Rule of Three (Five), and to copy all of the existing elements, when reallocating memory to increase to the necessary amount.


The much better choice than doing it all yourself (which is likely to be error prone), is to use a

std::vector<int> dyn_point;

and/or alike in your class.

Memory management is taken care of in the container implementations, and you don't need to bother about it.

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • Thanks a lot for the explanation, the book I'm learning from doesn't seem to get into using `vector` for another ~50 pages so I was attempting to solve my problem without it. – FutureWizard Apr 21 '15 at 02:29
  • @FutureWizard There's some good reference and examples you can examine from that link I'd given to the [_standard c++ container library_](http://en.cppreference.com/w/cpp/container) reference. It's still a pity that many text books, course scripts and tutorials try to teach manual memory allocation in 1st place. In practice you shouldn't have cases to use this, and it's seriously stuff for advanced usage of the language, not for beginners. – πάντα ῥεῖ Apr 21 '15 at 02:31
  • 1
    To be fair, the textbook doesn't go too far into manually allocating memory. I think it's important to give beginners, such as myself, an idea of how something works before teaching them an easier, automated way of doing it. Still, definitely using vector from now on. – FutureWizard Apr 21 '15 at 02:42
  • @FutureWizard _"Still, definitely using vector from now on."_ Good decision!! :) (I'm glad having saved another soul! You should know, [I'm an evangelist of this opinion](http://dev-jungle.blogspot.de/2015/02/software-development-in-wild-i-have.html)) – πάντα ῥεῖ Apr 21 '15 at 02:49
  • @FutureWizard _"the textbook doesn't go too far into manually allocating memory"_ That's probably because it's hard to teach this for a beginner's viewpoint, and it's totally confusing concepts of correctly using [RAII](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization) with class instantiations. As mentioned `new`/`delete` isn't for beginners, but very advanced, and rarely used stuff. – πάντα ῥεῖ Apr 21 '15 at 03:00