3

Could you help me organize a dynamic array of points?

I have coped with a dynamic array of integers. But I don't know how to organize it with structures.

Here is my code so far...

#include "stdafx.h"
#include <cstdlib>;
#include <iostream>;
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
  int i = 0; // Array index.
  struct Point
  {
    int x;
    int y;
  };
  size_t n = sizeof(int);
  int * points = static_cast<int*>(malloc(n));
  char command;
  do
  {
    cout << "n - Create new point." << endl;
    cout << "q - Quit." << endl;
    cout << "Input a new command: ";
    cin >> command;
    if (command == 'n')
    {
      points[i] = 1;
      i++;
      /* points[i] = new Point();
         points[i].x = 1;
         points[i].y = 1; */
      // cout<<"("<<point1.x<<","<<point1.y<<")";               
    }               
    else if (command == 'q')
    {       
      for (int j = 0; j < i; j++)
        cout << points[j] <<endl;
      system("pause");
      return 0;
    }
    else
    {
      cout << "Please, enter a correct command." << endl << endl << endl;               
    }
  } while (true);
  system("pause");  
  return 0;
}
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
Kifsif
  • 3,477
  • 10
  • 36
  • 45

4 Answers4

3

look into vectors

#include <vector>

http://www.mochima.com/tutorials/vectors.html

iedoc
  • 2,266
  • 3
  • 30
  • 53
3

std::vector is a sequence container that encapsulates dynamic size arrays.

--cppreference.com

This is what you should use in C++, rather than a dynamically-allocated array of structs as you would in C.

Here is how you can start to incorporate this into your code (untested)...

#include <vector>
#include <iostream>

struct Point
{
    int x;
    int y;
};

typedef std::vector<Point> PointVector;

int main()
{
    using std::cout;
    using std::cin;
    using std::endl;

    PointVector points;

    char command = 0;
    do
    {
        cout << "n - Create new point." << endl;
        cout << "q - Quit." << endl;
        cout << "Input a new command: ";
        cin >> command;

        if (command == 'n')
        {
            Point new_point;
            new_point.x = 1;
            new_point.y = 1;
            points.push_back(new_point);
            cout << "(" << new_point.x << "," << new_point.y << ")\n";
        }
        else if (command == 'q')
        {
            for (PointVector::iterator it = points.begin(), end = points.end();
                it != end;
                ++it)
            {
                cout << "(" << it->x << "," << it->y << ")\n";
            }
            break;
        }
        else
        {
            cout << "Please, enter a correct command." << endl;
        }
    } while(true);
}

Key points:

  1. typedefs often make code more readable
  2. std::vector::push_back() adds to the end of the container, without you needing to keep an index or be overly-concerned about size.
  3. Iterators (such as the one returned by std::vector::begin()) make it easy to access the elements within the container, again without needing to keep an index. See also Why use iterators instead of array indices?
  4. This implementation would not leak points as your malloc() based implementation would do.
Community
  • 1
  • 1
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
  • how do we take care of the memory management of `points` ? Doesn't it have to be deleted at the end ? – locke14 Apr 04 '14 at 07:47
  • @locke14: `std::vector`'s [allocator](http://en.cppreference.com/w/cpp/concept/Allocator) will take care of `points` when it goes out of [scope](http://en.cppreference.com/w/cpp/language/scope). `points` *must not* be `delete`d manually. – johnsyweb Apr 04 '14 at 09:11
  • Thanks for the clarification. What if `points` contains an integer array ? Will the array's memory be freed as well ? – locke14 Apr 04 '14 at 09:50
  • 1
    Even then! There should be no need for you to call `delete` in modern C++! Here's some light reading for your weekend: http://herbsutter.com/elements-of-modern-c-style/ – johnsyweb Apr 04 '14 at 10:09
2

By the look of it, you are using malloc to grab enough memory to store a pointer to an int. Dont use malloc / free. This is C++, use new or delete if you really have to.

Thankfully, this is an occasion where you don't have to worry about dynamically allocating memory as you can do all this in a vector as follows:

// First create a vector of points.
std::vector<Points> points;

// Now create the Point (i'm assuming you were going to read
// it from the input stream here.)
cin >> x >> y;
Point p;
p.x = x;
p.y = y;

// And add it to the vector.
points.push_back( p );

It's that simple, you don't need to worry about increasing the capacity of the points vector or clearing it down at the end.

Component 10
  • 10,247
  • 7
  • 47
  • 64
1

You can use vectors as @iedoc suggested:

#include <iostream>;
#include <vector>;

using namespace std;

struct SPoint
{
    int X;
    int Y;
};

int main()
{
    vector<SPoint> points;

    char command;
    do
    {
        cout << "n - Create new point." << endl;
        cout << "q - Quit." << endl;
        cout << "Input a new command: ";

        cin >> command;

        if (command == 'n')
        {
            int x = 0;
            int y = 0;

            cout << "X: ";
            cin >> x;

            cout << "Y: ";
            cin >> y;

            SPoint point = { x, y};
            points.push_back(point);
        }

        else if (command == 'q')
        {
            for (int i = 0; i < points.size(); ++i)
            {
                cout << "(" << points[i].X << "," << points[i].Y << ")";
            }

            return 0;
        }
        else
        {
            cout << "Please, enter a correct command."<<endl<<endl<<endl;
        }
    }

    while(true);

    return 0;
}
AngelCastillo
  • 2,385
  • 2
  • 18
  • 26