0

I'm trying to get used to C++. I want to add an object in a dynamic array each time I read a line from a file without knowing the dimension.

I declared a pointer to array like this:

Rlmr *myArray;

where Rlmr is a class with a public string as id.

Now I read a file line by line and after that I want to add an object to myArray

        index = 0;
        while (fgets(buffer, MAXSIZEBUFFER, fp) != NULL) {
            if(buffer[0] == '#') // Skip comment lines
                continue;
            else {
                sscanf(...);
                index++;
            }
        // At this point I want a new object in the array
        myArray = (Rlmr*) malloc(sizeof (Rlmr) * index);
        // Here I try to call the object constructor by passing the id
        myArray[index-1] = new Rlmr(cBeacId);
        }

I don't understand then the error from the compiler:

error: no match for âoperator=â in â*(myArray+ ((unsigned int)(((unsigned int)index) * 28u))) = (operator new(28u), (<statement>, ((Rlmr*)<anonymous>)))â

What is wrong. And, how could it be done using std::vector. I'd like to understand both ways, thanks.

Dad85
  • 33
  • 1
  • 1
  • 9
  • 7
    Several things are wrong. `malloc`. `malloc` is C, not C++. C++ code uses `new`. Furthermore, you should not even be using either `malloc` or `new`, but you should use `std::vector`, and let it worry about automatically resizing your array. If you want "to get used to C++", the best way to do so is to learn how to use C++ containers properly. Modern C++ code rarely needs to dynamically allocate any memory. And if you want to use how to use `std::vector`, your C++ book will give a far better explanation than a brief answer on stackoverflow.com – Sam Varshavchik Nov 08 '16 at 12:04
  • ... especially if the book comes from a [list of good C++ books](http://stackoverflow.com/q/388242/1782465) – Angew is no longer proud of SO Nov 08 '16 at 12:20

2 Answers2

1

First of all don't use malloc to allocate objects dynamically. Instead use new (or new[] if allocating an array).

Now for your problem. The array is an array of objects, not an array of pointers to objects. And new Rlmr(cBeacId) results in a *pointerto aRlmr` object. That is why you get an error.

One way to solve your problem is to use a std::vector (which should always be the "go to" default container). Then you can do something like

std::vector<Rlmr> myArray;

while (...)
{
    ...
    myArray.emplace_back(cBeacId);
}

Besides that you should really learn how to use the standard C++ stream facilities and the string class. In the long run it will make your life as a C++ programmer so much easier, especially when you can start using some of the standard algorithm functions in creative ways.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

What is wrong? new returns a pointer. In the following line you are trying to assign a pointer to an existing object:

myArray[index-1] = new Rlmr(cBeacId);

Instead you should write:

new (myArray + index - 1) Rlmr(cBeacId);

Which is called "placement new" (cf here). This solves your problem, but should not satisfy anyone.

Second, how to do this with vector:

std::vector<Rlmr> data;

while (fgets(buffer, MAXSIZEBUFFER, fp) != NULL) {
    if(buffer[0] == '#') // Skip comment lines
        continue;
    else {
        sscanf(...);
    }
    data.emplace_back(cBeacId);
}

Details on vector eg. vector::emplace_back are available here.

Community
  • 1
  • 1
m8mble
  • 1,513
  • 1
  • 22
  • 30