0

In my code, I want to create a dynamic array of objects. I don't know how many objects I want until the runtime, and the array's class has a dynamic variable array, so my objects can be of any size. Therefore, to make an array of them, I want to create an array of pointers as pointers are of a fixed size. Then, during runtime, when I know how many objects I will store, I want to malloc the memory needed to store the pointers. When I try mallocing, I get a linking error unless I define the array at the top of the .cpp file, even though it's already declared in the header .h file, and I am not sure why this is necessary.

My code: Maintest.cpp

#include <iostream>

#include "class.h"

#include "Maintest.h"

//Class** Maintest::testArray = NULL; //uncommenting this line fixes the linking error

void Maintest::createMany(){
    testArray = (Class **) malloc(10 * sizeof(Class *));
}

int main(){
    printf("hello");
}

Maintest.h

class Maintest {
private:
    static Class** testArray;
public:
    static void createMany();
};

class.cpp

#include <iostream>

#include "class.h"

Class::Class(int arg){
    test = arg;
}

class.h

class Class {
private:
    int test;
public: 
    Class::Class(int);
};
s4342re41
  • 103
  • 8
  • Does this answer your question? [Undefined reference to static class member](https://stackoverflow.com/questions/272900/undefined-reference-to-static-class-member) – Adrian Mole Oct 26 '20 at 16:50
  • 1
    It's the rules of C++, you even said it yourself. You need a declaration (in this case in the header file) and a definition (in this case at the top of the C++ file). In some cases the same code can be declaration and a definition but this is not one of those cases. Plus why are you using malloc in a C++ program? It's bad enough that you are trying to create your own dynamic array (what's wrong with `std::vector`?) but at least do it with `new` instead of malloc. – john Oct 26 '20 at 16:50
  • Please, have a look at [std::vector](https://en.cppreference.com/w/cpp/container/vector). – Scheff's Cat Oct 26 '20 at 16:51
  • 1
    In `Class` declaration `Class::Class(int);` should be `Class(int);` – anastaciu Oct 26 '20 at 16:55
  • @john So to get this right, I can't allocate memory to an array declared in the header file unless I define it with any value, including null, in the .cpp file? – s4342re41 Oct 26 '20 at 16:55
  • @s4342re41 No, it has nothing to do with allocation or arrays. You cannot declare a static member of a class, unless you also define it separately (there are exceptions however). It's a similar case to a global variable, they also are usually declared and separately defined. C++ is complex language. A [good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) will explain all of this – john Oct 26 '20 at 19:06

1 Answers1

1

In olden times, it wasn't enough to declare a static variable in your class; you had to define it in exactly one source file. This is why uncommenting that line fixes your linker error.

But since C++17, you can get round this by declaring the variable as static inline in the class definition:

class Maintest {
private:
    static inline Class** testArray;
public:
    static void createMany();
};
TonyK
  • 16,761
  • 4
  • 37
  • 72
  • I see. So allocating memory wouldn't count as a definition then I assume? – s4342re41 Oct 26 '20 at 16:59
  • This is nothing to do with memory allocation. It is the reference to `testArray` in `createMany()` that is causing the problem, not the memory allocation. – TonyK Oct 26 '20 at 17:00
  • I see, so unless I define the static variable somewhere in my class, I can't define it inside the function belonging to that class? Is there a reason why this was the case? – s4342re41 Oct 26 '20 at 17:03
  • "somewhere in my class"? What does that mean? You are _declaring_ it in your class; and you have to _define_ it somewhere else. At least, you did have to, until `static inline` came along. – TonyK Oct 26 '20 at 17:06
  • Right. I meant I need to define it somewhere in (e.g. at the top) my .cpp file, before I can use it in my class (i.e. when I am defining a method belonging to the same class as the static variable). – s4342re41 Oct 26 '20 at 17:08
  • You have to define it in exactly one .cpp file. (Unless you use `static inline`, in which case you don't need to define it anywhere.) – TonyK Oct 26 '20 at 17:11