initializing static (shared) array?

May 17, 2011 at 1:32pm
Hi -

I have a class whose objects should share an array of coefficients. Normally, I'd make the shared element(s) static, but...I initialize their value from reading a file. Any ideas how I can:

1) initialize this array
2) keep only one copy among all objects within the class

Thanks.
May 17, 2011 at 2:31pm
Making something static doesn't make it constant. I don't see what problems you could be having with initializing a static array at run time..
May 17, 2011 at 2:35pm
I know it's not constant; that's not necessary.

I was hoping to initialize the array when the constructor was invoked for the first time, but I don't see a clean way to do that.
May 17, 2011 at 3:50pm
Just write a static function Initialize() and call it in main.
If you want to do this from the constructor, you'll need to know whether the array has already been initialized. Either have a static boolean "initialized" and check it in the ctor or use a dynamic array and check if the pointer is null. Though there is no need to bind initialization of static members to a ctor.
May 17, 2011 at 5:33pm
Is this a C-style array? You could:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

using std::cout;
using std::endl;

class MyClass
{
public:
	static const double Coefficients[];
};

const double MyClass::Coefficients[] = { 1, 2, 3 };

#ifndef _countof
#define _countof(x) (sizeof(x) / sizeof(x[0]))
#endif

int main()
{
    for(int i = 0; i < _countof(MyClass::Coefficients); i++) cout << MyClass::Coefficients[i] << endl;
}


Line 12 will be run before main() by the CRT.
Last edited on May 17, 2011 at 5:52pm
May 17, 2011 at 7:10pm
That's a clever approach, Jose, and I'm going to remember it. I think, though, that Hamsterman is probably right; I was trying to get too "clever" for my own good. I'll just include something in main() that calls the function a bunch of times.

Thanks, guys.
May 17, 2011 at 8:57pm
Well, it turns out that I get a build-time error when I try to make member data static. Here's a snippet from the declaration:
1
2
private:
	static	long	coeffI[NBR_CELLS];


I reference the static variable twice, as arguments to non-member functions.

The error message I get is:

Undefined symbols:
"DemodShaper::coeffI", referenced from:
__ZN11DemodShaper6coeffIE$non_lazy_ptr in DemodShaper.o
(maybe you meant: __ZN11DemodShaper6coeffIE$non_lazy_ptr)
ld: symbol(s) not found


Any ideas what I'm doing wrong here? Thanks.
Last edited on May 17, 2011 at 9:01pm
May 17, 2011 at 9:08pm
Show code.
May 17, 2011 at 9:12pm
OK, here's the first time it's referenced:

1
2
3
4
5
6
7
8
9
long	DemodShaper::initCoeff()
{
	string s;
	s = "coeffI.txt";
	getCoeff (s, NBR_CELLS, coeffI);
	s = "coeffQ.txt";
	getCoeff (s, NBR_CELLS, coeffQ);
	return 0;
}


And here's the second (different function):
1
2
3
4
5
6
			cellArrayI.at(i).cycle(cellSampleInputI,		// I.
								coeffI[i],
								cellSumInputI,
								feedbackInputI,
								clockEnable,
								resetFlag);
May 17, 2011 at 9:16pm
The use of the array seems OK. Show the definition of NBR_CELLS, please.

Also make sure you are not trying to access the array from outside of the DemodShaper class.
May 17, 2011 at 9:22pm
(in an include file)

const long NBR_CELLS=32;

And, as I said, both function calls are non-member functions. But, since I'm just passing an address, it shouldn't matter, right?
May 17, 2011 at 9:27pm
It matters because the identifier "DemodShaper::coeffI" is only known inside DemodShaper. If you want direct access to the array from outside the class, the array needs to be public.
May 17, 2011 at 9:32pm
But, to the called routines, it's just a pointer to a long. I'm not trying to actually reference the private element, just read from and write to its address. Isn't that OK, or am I going brain-dead?
May 17, 2011 at 9:41pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void PrintValue(const long someArr[], int index)
{
    //It is only here where you "just get an address".  Not in the function calls.
    cout << "I can access the array:  " << someArr[index];
}

class SomeClass
{
private:
    static const long Arr[];

public:
    void Foo();
};

const SomeClass::Arr[] = { 1, 2, 3, 4, 5 };

void SomeClass::Foo()
{
    PrintValue(SomeClass::Arr, 3); //Correct:  This is a method inside the class.
}

void OutsideFoo()
{
    PrintValue(SomeClass::Arr, 2); // Error:  An outside function such as OutsideFoo() cannot access SomeClass::Arr.
}
Last edited on May 17, 2011 at 9:42pm
May 17, 2011 at 9:43pm
BTW, in a header file you should have:

extern const long NBR_CELLS;

And in a single CPP file you would have what you currently have now in your header file.
May 17, 2011 at 9:46pm
Maybe I wasn't clear above: the second example I posted is from within a member function. Accordingly, it has access to the private data. Even though it's passing it to a non-member function, shouldn't it still be OK?
May 17, 2011 at 9:57pm
If I declare the constant as external in my header file, I can't use it to bound the arrays I define in the class.
May 17, 2011 at 10:01pm
I see. But since the arrays are private, so should its length, I would think. Make NBR_CELLS a private member of DemodShaper? Just a suggestion. Whatever works for you.
May 17, 2011 at 10:03pm
But, this isn't causing my problem, is it? I still need to figure out how to get rid of this build error.
May 18, 2011 at 12:15am
So, to summarize...if I remove the static qualifier from the class definition, everything is OK. But, when I add "static" I get the build error mentioned above. Anyone have an idea about what's going on?

EDIT:

Found it! I'd forgotten to define the arrays outside of the class. (I'd forgotten about that aspect of static members.)

Thanks for the help, guys.
Last edited on May 18, 2011 at 12:55am
Topic archived. No new replies allowed.