Clearing static std::vector fails

  • Thread starter Martin Magnusson
  • Start date
M

Martin Magnusson

I'm having trouble clearing and resizing a static std::vector of
std::vectors (segmentation fault). Is it OK to call clear() and resize()
on a static attribute? My code is similar to the one posted below. The
code below works, though. My original code crashes on the second call to
X::f().

My question is: is this code valid, or is it just a coincidence that it
doesn't crash?



#include <iostream>
#include <vector>
using namespace std;

class X
{
private:
static vector< vector< int > > v;
public:
void f( unsigned x, unsigned y )
{
v.clear();
v.resize( x );
for (unsigned Y = 0; Y < x; ++Y)
v[Y].resize( y );
for (unsigned X = 0; X < x; ++X)
for (unsigned Y = 0; Y < y; ++Y)
v[X][Y] = 10*X + Y;
}

};

vector< vector< int > > X::v;

int main( )
{
X x;
x.f(10,10);
x.f(5,5);
x.f(15, 15);
return 0;
}
 
V

Victor Bazarov

Martin said:
I'm having trouble clearing and resizing a static std::vector of
std::vectors (segmentation fault). Is it OK to call clear() and resize()
on a static attribute? My code is similar to the one posted below. The
code below works, though. My original code crashes on the second call to
X::f().

What's the damn point of posting working code when yours has a problem?
My question is: is this code valid, or is it just a coincidence that it
doesn't crash?

The class you store in the vectors (compared to the 'int' in the code
below) probably has some dynamic memory management ('new' in the c-tor
and 'delete' in the d-tor) which is screwed up (like not following the
"Rule of Three"). Without seeing the actual code it is impossible to
really help.
#include <iostream>
#include <vector>
using namespace std;

class X
{
private:
static vector< vector< int > > v;
public:
void f( unsigned x, unsigned y )
{
v.clear();
v.resize( x );
for (unsigned Y = 0; Y < x; ++Y)
v[Y].resize( y );
for (unsigned X = 0; X < x; ++X)
for (unsigned Y = 0; Y < y; ++Y)
v[X][Y] = 10*X + Y;
}

};

vector< vector< int > > X::v;

int main( )
{
X x;
x.f(10,10);
x.f(5,5);
x.f(15, 15);
return 0;
}

The code is valid. It doesn't make much sense to me that a non-static
member function of a class changes a static data member, but I guess
your particular design calls for it.

V
 
M

Matt Wharton

Martin Magnusson said:
I'm having trouble clearing and resizing a static std::vector of
std::vectors (segmentation fault). Is it OK to call clear() and resize()
on a static attribute? My code is similar to the one posted below. The
code below works, though. My original code crashes on the second call to
X::f().

My question is: is this code valid, or is it just a coincidence that it
doesn't crash?



#include <iostream>
#include <vector>
using namespace std;

class X
{
private:
static vector< vector< int > > v;
public:
void f( unsigned x, unsigned y )
{
v.clear();
v.resize( x );
for (unsigned Y = 0; Y < x; ++Y)
v[Y].resize( y );
for (unsigned X = 0; X < x; ++X)
for (unsigned Y = 0; Y < y; ++Y)
v[X][Y] = 10*X + Y;
}

};

vector< vector< int > > X::v;

int main( )
{
X x;
x.f(10,10);
x.f(5,5);
x.f(15, 15);
return 0;
}

Calling clear() and resize() on a vector that happens to be a static member
is no different than calling it on some other vector.

I haven't explicitly tried, but I'm pretty sure the code you posted won't
compile. Is X a class name or a index variable in your for loops? Based on
this example, it's hard to know for sure what you intend your code to do.

-Matt
 
V

Victor Bazarov

Matt said:
[...]
I haven't explicitly tried, but I'm pretty sure the code you posted won't
compile. Is X a class name or a index variable in your for loops? Based on
this example, it's hard to know for sure what you intend your code to do.

You should explicitly try before expressing such assuredness. The code
compiles just fine. The variable X and type X do not interfere with each
other. This:

class A {};
int main() {
A a;
int A;
}

is a perfectly valid C++ program.

V
 
M

Matt Wharton

Victor Bazarov said:
Matt said:
[...]
I haven't explicitly tried, but I'm pretty sure the code you posted won't
compile. Is X a class name or a index variable in your for loops? Based
on this example, it's hard to know for sure what you intend your code to
do.

You should explicitly try before expressing such assuredness. The code
compiles just fine. The variable X and type X do not interfere with each
other. This:

class A {};
int main() {
A a;
int A;
}

is a perfectly valid C++ program.

Ok, you got me--fair enough :). I'll still contend however that, even
though this is technically a "valid C++ program", this kind of a coding
practice (using a type name as a variable name) doesn't make for readable
code and it doesn't provide any tangible benefit (that I can see). If I
were on the standards committee, I would have voted against this, but what
do I know? :p

-M
 
J

Josh

Victor Bazarov said:
You should explicitly try before expressing such assuredness. The code
compiles just fine. The variable X and type X do not interfere with each
other. This:

class A {};
int main() {
A a;
int A;
}

is a perfectly valid C++ program.

I see that this is true, but could you explain why the following
is not valid C++:

----
struct foo {};

struct bar {
foo foo;
};

int main()
{
bar bar;
foo foo;
}
----

Rename or remove the foo member from bar and the compiler is
happy, otherwise I get (using g++ 3.2):

t.cc:4: declaration of `foo bar::foo'
t.cc:1: changes meaning of `foo' from `struct foo'

....which I don't quite understand.

Josh
 
V

Victor Bazarov

Josh said:
I see that this is true, but could you explain why the following
is not valid C++:

----
struct foo {};

struct bar {
foo foo;
};

int main()
{
bar bar;
foo foo;
}
----

Rename or remove the foo member from bar and the compiler is
happy, otherwise I get (using g++ 3.2):

t.cc:4: declaration of `foo bar::foo'
t.cc:1: changes meaning of `foo' from `struct foo'

Is that a warning or an error message?
...which I don't quite understand.

If it is in fact an error message, the only explanation to that is that
g++ 3.2 has a bug in that area. The code is valid.

If it is in fact a warning, what do you not understand? It warns you that
inside the class 'bar' the use of 'foo' after that declaration is
different than before that declaration or outside the class. So, if you
later write something that uses 'foo' you will get bar's member instead of
the global type-id.

V
 
J

Josh

Victor Bazarov said:
Josh wrote:

Is that a warning or an error message?

An error message. Interesting, the only difference in output
between g++ 3.2 and 3.4 is the addition of "error: ":

t.cc:4: error: declaration of `foo bar::foo'
t.cc:1: error: changes meaning of `foo' from `struct foo'
If it is in fact an error message, the only explanation to that
is that g++ 3.2 has a bug in that area. The code is valid.

If it is in fact a warning, what do you not understand? It
warns you that inside the class 'bar' the use of 'foo' after
that declaration is different than before that declaration or
outside the class. So, if you later write something that uses
'foo' you will get bar's member instead of the global type-id.

Ah, okay. The error text makes sense now. What I don't
understand is why the complier can clearly distinguish the two
inside the scope of main, but not inside the class definition.

The reason I'm bringing this up is that we ran into this issue at
work when a header including a similar structure definition was
included into a c++ source file. Previously, it had only been
built with gcc which does not seem to have a problem with the
syntax.

Josh
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,184
Messages
2,570,978
Members
47,561
Latest member
gjsign

Latest Threads

Top