Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   structures, structures and more structures (questions about nestedstructures) (http://www.velocityreviews.com/forums/t439526-structures-structures-and-more-structures-questions-about-nestedstructures.html)

Alfonso Morra 09-24-2005 01:18 AM

structures, structures and more structures (questions about nestedstructures)
 
Hi,

I have the ff data types :

typedef enum {
VAL_LONG ,
VAL_DOUBLE ,
VAL_STRING ,
VAL_DATASET
}ValueTypeEnum ;

typedef union {
long lval ;
double fval ;
char* sval ;
void* ptr ;
} Value ;

typedef struct {
int magic ;
int version ;
}Header ;

typedef struct {
char label[20] ;
id int ;
}Key ;

typedef struct {
Header *hdr ;
char *subject ;
int subject_len ;
Key key ;
ValueTypeEnum type ;
Value value ;
int text_len ;
int size ;
}MotherStruct ;


If I have a variable declared as ff:

MotherStruct *pMS = calloc(1,sizeof(MotherStruct*)) ;

1). Do I have to allocate memory seperately for each individual nested
pointer in the structure (i.e. hdr and subject?). I guess the answer is
yes - but I just need to be sure (see question 3 below).

2). How do I calculate the size (in bytes) of the structure MotherStruct
- so that I can use a function like memcpy to copy this memory block to
another memory block ?

3). Finally, (this is related in a way to the first question). If I just
call free on pMS is all the memory that was allocated freed (is the
answer the same if I have to issue seperate calls to allocate memory to
the individual nested pointers - i.e. will a single call to free(pMs)
free any memory allocated to pointers nested within the structure - OR
do I need to free each of the nested pointers before finally freeing the
memory block pointed to by pMS ?

Tkx



Mike Wahler 09-24-2005 01:59 AM

Re: structures, structures and more structures (questions about nested structures)
 

"Alfonso Morra" <sweet-science@the-ring.com> wrote in message
news:dh29hu$o4i$1@nwrdmz02.dmz.ncs.ea.ibs-infra.bt.com...
> Hi,
>
> I have the ff data types :
>
> typedef enum {
> VAL_LONG ,
> VAL_DOUBLE ,
> VAL_STRING ,
> VAL_DATASET }ValueTypeEnum ;
>
> typedef union {
> long lval ;
> double fval ;
> char* sval ;
> void* ptr ;
> } Value ;
>
> typedef struct {
> int magic ;
> int version ;
> }Header ;
>
> typedef struct {
> char label[20] ;
> id int ;
> }Key ;
>
> typedef struct {
> Header *hdr ;
> char *subject ;
> int subject_len ;
> Key key ;
> ValueTypeEnum type ;
> Value value ;
> int text_len ;
> int size ;
> }MotherStruct ;
>
>
> If I have a variable declared as ff:
>
> MotherStruct *pMS = calloc(1,sizeof(MotherStruct*)) ;
>
> 1). Do I have to allocate memory seperately for each individual nested
> pointer in the structure (i.e. hdr and subject?).


Yes, if you want those pointers to point to objects of
those types.

> I guess the answer is yes - but I just need to be sure (see question 3
> below).
>
> 2). How do I calculate the size (in bytes) of the structure MotherStruct


sizeof(MotherStruct)

> - so that I can use a function like memcpy to copy this memory block to
> another memory block ?


Also remember you'll need to allocate memory for the pointers
to point to.

>
> 3). Finally, (this is related in a way to the first question). If I just
> call free on pMS is all the memory that was allocated freed


No. Each call to 'malloc()' must be matched by a call to 'free()'

> (is the answer the same if I have to issue seperate calls to allocate
> memory to the individual nested pointers - i.e. will a single call to
> free(pMs) free any memory allocated to pointers nested within the
> structure



No.

- OR
> do I need to free each of the nested pointers before finally freeing the
> memory block pointed to by pMS ?


Match each 'malloc()' with a 'free()'

And don't forget to test the return value for each call to
'malloc()' (it will return NULL if it fails).

-Mike



Alfonso Morra 09-24-2005 02:21 AM

Re: structures, structures and more structures (questions about nestedstructures)
 


Mike Wahler wrote:

> "Alfonso Morra" <sweet-science@the-ring.com> wrote in message
> news:dh29hu$o4i$1@nwrdmz02.dmz.ncs.ea.ibs-infra.bt.com...
>
>>Hi,
>>
>>I have the ff data types :
>>
>>typedef enum {
>>VAL_LONG ,
>>VAL_DOUBLE ,
>>VAL_STRING ,
>>VAL_DATASET }ValueTypeEnum ;
>>
>>typedef union {
>>long lval ;
>>double fval ;
>>char* sval ;
>>void* ptr ;
>>} Value ;
>>
>>typedef struct {
>>int magic ;
>>int version ;
>>}Header ;
>>
>>typedef struct {
>>char label[20] ;
>>id int ;
>>}Key ;
>>
>>typedef struct {
>>Header *hdr ;
>>char *subject ;
>>int subject_len ;
>>Key key ;
>>ValueTypeEnum type ;
>>Value value ;
>>int text_len ;
>>int size ;
>>}MotherStruct ;
>>
>>
>>If I have a variable declared as ff:
>>
>>MotherStruct *pMS = calloc(1,sizeof(MotherStruct*)) ;
>>
>>1). Do I have to allocate memory seperately for each individual nested
>>pointer in the structure (i.e. hdr and subject?).

>
>
> Yes, if you want those pointers to point to objects of
> those types.
>
>
>> I guess the answer is yes - but I just need to be sure (see question 3
>>below).
>>
>>2). How do I calculate the size (in bytes) of the structure MotherStruct

>
>
> sizeof(MotherStruct)



This is the only answer that suprised me (in fact I don't believe its
the correct answer). I used to think this was the correct answer. But if
you think about it, it can't be (at least, I can't see how it can be).
How can sizeof know how much memory you have allocated for the char*
(for example)?. The number returned by sizeof is independent of the size
of the string that has been allocated for the member subject - so I
think sizeof can be used for a simple structure with basic data types -
whenever you have nested pointers, all bets are off. I think the correct
way of doing this is to navigate the structure and sum up
(sizeof(data_type) x number of data_type) all the way through all the
members of the struct and any nested pointers - that makes sense from a
logical point of view - but it would be great if someone could either
confirm it or point me to a reference that shows me why my thinking is
wrong.

But thanks for the other two answers.


>
>
>>- so that I can use a function like memcpy to copy this memory block to
>>another memory block ?

>
>
> Also remember you'll need to allocate memory for the pointers
> to point to.
>
>
>>3). Finally, (this is related in a way to the first question). If I just
>>call free on pMS is all the memory that was allocated freed

>
>
> No. Each call to 'malloc()' must be matched by a call to 'free()'
>
>
>>(is the answer the same if I have to issue seperate calls to allocate
>>memory to the individual nested pointers - i.e. will a single call to
>>free(pMs) free any memory allocated to pointers nested within the
>>structure

>
>
>
> No.
>
> - OR
>
>>do I need to free each of the nested pointers before finally freeing the
>>memory block pointed to by pMS ?

>
>
> Match each 'malloc()' with a 'free()'
>
> And don't forget to test the return value for each call to
> 'malloc()' (it will return NULL if it fails).
>
> -Mike
>
>



Mike Wahler 09-24-2005 02:32 AM

Re: structures, structures and more structures (questions about nested structures)
 

"Alfonso Morra" <sweet-science@the-ring.com> wrote in message
news:dh2d7e$g16$1@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
>
>
> Mike Wahler wrote:
>
>> "Alfonso Morra" <sweet-science@the-ring.com> wrote in message
>> news:dh29hu$o4i$1@nwrdmz02.dmz.ncs.ea.ibs-infra.bt.com...
>>
>>>Hi,
>>>
>>>I have the ff data types :
>>>
>>>typedef enum {
>>>VAL_LONG ,
>>>VAL_DOUBLE ,
>>>VAL_STRING ,
>>>VAL_DATASET }ValueTypeEnum ;
>>>
>>>typedef union {
>>>long lval ;
>>>double fval ;
>>>char* sval ;
>>>void* ptr ;
>>>} Value ;
>>>
>>>typedef struct {
>>>int magic ;
>>>int version ;
>>>}Header ;
>>>
>>>typedef struct {
>>>char label[20] ;
>>>id int ;
>>>}Key ;
>>>
>>>typedef struct {
>>>Header *hdr ;
>>>char *subject ;
>>>int subject_len ;
>>>Key key ;
>>>ValueTypeEnum type ;
>>>Value value ;
>>>int text_len ;
>>>int size ;
>>>}MotherStruct ;
>>>
>>>
>>>If I have a variable declared as ff:
>>>
>>>MotherStruct *pMS = calloc(1,sizeof(MotherStruct*)) ;
>>>
>>>1). Do I have to allocate memory seperately for each individual nested
>>>pointer in the structure (i.e. hdr and subject?).

>>
>>
>> Yes, if you want those pointers to point to objects of
>> those types.
>>
>>
>>> I guess the answer is yes - but I just need to be sure (see question 3
>>> below).
>>>
>>>2). How do I calculate the size (in bytes) of the structure MotherStruct

>>
>>
>> sizeof(MotherStruct)

>
>
> This is the only answer that suprised me (in fact I don't believe its the
> correct answer).


Yes, it is correct. It will return the number of bytes used
by a type 'MotherStruct' object. This size includes the size
of all members, including pointers. What those pointers point
to (if anything) is not part of the 'MotherStruct' object.

> I used to think this was the correct answer.


It is.

>But if you think about it, it can't be (at least, I can't see how it can
>be). How can sizeof know how much memory you have allocated for the char*
>(for example)?.


It doesn't. That memory is not part of the 'MotherStruct' object,
only the pointer is.

>The number returned by sizeof is independent of the size of the string that
>has been allocated for the member subject


Yes, because that memory is not part of MotherStruct.

>- so I think sizeof can be used for a simple structure with basic data
>types -


Yes. Pointers are such types. Again, what they point to is not
part of the structure.

> whenever you have nested pointers, all bets are off.


Nope.

>I think the correct way of doing this is to navigate the structure and sum
>up (sizeof(data_type) x number of data_type) all the way through all the
>members of the struct and any nested pointers - that makes sense from a
>logical point of view - but it would be great if someone could either
>confirm it or point me to a reference that shows me why my thinking is
>wrong.


Perhaps you asked the wrong question. :-) Yes, if you want to calculate
the size of all memory (including allocated) *associated* with MotherStruct,
that's how to do it.

Your question was:
2). How do I calculate the size (in bytes) of the structure MotherStruct

The correct answer is what I gave:
sizeof(MotherStruct).

>
> But thanks for the other two answers.


You're welcome.

-Mike



Alfonso Morra 09-24-2005 04:15 AM

Re: structures, structures and more structures (questions about nestedstructures)
 


Mike Wahler wrote:

> "Alfonso Morra" <sweet-science@the-ring.com> wrote in message
> news:dh2d7e$g16$1@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
>
>>
>>Mike Wahler wrote:
>>
>>
>>>"Alfonso Morra" <sweet-science@the-ring.com> wrote in message
>>>news:dh29hu$o4i$1@nwrdmz02.dmz.ncs.ea.ibs-infra.bt.com...
>>>
>>>
>>>>Hi,
>>>>
>>>>I have the ff data types :
>>>>
>>>>typedef enum {
>>>>VAL_LONG ,
>>>>VAL_DOUBLE ,
>>>>VAL_STRING ,
>>>>VAL_DATASET }ValueTypeEnum ;
>>>>
>>>>typedef union {
>>>>long lval ;
>>>>double fval ;
>>>>char* sval ;
>>>>void* ptr ;
>>>>} Value ;
>>>>
>>>>typedef struct {
>>>>int magic ;
>>>>int version ;
>>>>}Header ;
>>>>
>>>>typedef struct {
>>>>char label[20] ;
>>>>id int ;
>>>>}Key ;
>>>>
>>>>typedef struct {
>>>>Header *hdr ;
>>>>char *subject ;
>>>>int subject_len ;
>>>>Key key ;
>>>>ValueTypeEnum type ;
>>>>Value value ;
>>>>int text_len ;
>>>>int size ;
>>>>}MotherStruct ;
>>>>
>>>>
>>>>If I have a variable declared as ff:
>>>>
>>>>MotherStruct *pMS = calloc(1,sizeof(MotherStruct*)) ;
>>>>
>>>>1). Do I have to allocate memory seperately for each individual nested
>>>>pointer in the structure (i.e. hdr and subject?).
>>>
>>>
>>>Yes, if you want those pointers to point to objects of
>>>those types.
>>>
>>>
>>>
>>>>I guess the answer is yes - but I just need to be sure (see question 3
>>>>below).
>>>>
>>>>2). How do I calculate the size (in bytes) of the structure MotherStruct
>>>
>>>
>>>sizeof(MotherStruct)

>>
>>
>>This is the only answer that suprised me (in fact I don't believe its the
>>correct answer).

>
>
> Yes, it is correct. It will return the number of bytes used
> by a type 'MotherStruct' object. This size includes the size
> of all members, including pointers. What those pointers point
> to (if anything) is not part of the 'MotherStruct' object.
>
>
>> I used to think this was the correct answer.

>
>
> It is.
>
>
>>But if you think about it, it can't be (at least, I can't see how it can
>>be). How can sizeof know how much memory you have allocated for the char*
>>(for example)?.

>
>
> It doesn't. That memory is not part of the 'MotherStruct' object,
> only the pointer is.
>
>
>>The number returned by sizeof is independent of the size of the string that
>>has been allocated for the member subject

>
>
> Yes, because that memory is not part of MotherStruct.
>
>
>>- so I think sizeof can be used for a simple structure with basic data
>>types -

>
>
> Yes. Pointers are such types. Again, what they point to is not
> part of the structure.
>
>
>>whenever you have nested pointers, all bets are off.

>
>
> Nope.
>
>
>>I think the correct way of doing this is to navigate the structure and sum
>>up (sizeof(data_type) x number of data_type) all the way through all the
>>members of the struct and any nested pointers - that makes sense from a
>>logical point of view - but it would be great if someone could either
>>confirm it or point me to a reference that shows me why my thinking is
>>wrong.

>
>
> Perhaps you asked the wrong question. :-) Yes, if you want to calculate
> the size of all memory (including allocated) *associated* with MotherStruct,
> that's how to do it.
>
> Your question was:
> 2). How do I calculate the size (in bytes) of the structure MotherStruct
>
> The correct answer is what I gave:
> sizeof(MotherStruct).
>
>
>>But thanks for the other two answers.

>
>
> You're welcome.
>
> -Mike
>
>

Tkx for the clarification ;-)


Emmanuel Delahaye 09-24-2005 09:02 AM

Re: structures, structures and more structures (questions about nested structures)
 
Alfonso Morra wrote on 24/09/05 :
> Hi,
>
> I have the ff data types :
>
> typedef enum {
> VAL_LONG ,
> VAL_DOUBLE ,
> VAL_STRING ,
> VAL_DATASET
> }ValueTypeEnum ;
>
> typedef union {
> long lval ;
> double fval ;
> char* sval ;
> void* ptr ;
> } Value ;
>
> typedef struct {
> int magic ;
> int version ;
> }Header ;
>
> typedef struct {
> char label[20] ;
> id int ;
> }Key ;
>
> typedef struct {
> Header *hdr ;
> char *subject ;
> int subject_len ;
> Key key ;
> ValueTypeEnum type ;
> Value value ;
> int text_len ;
> int size ;
> }MotherStruct ;
>
> If I have a variable declared as ff:
>
> MotherStruct *pMS = calloc(1,sizeof(MotherStruct*)) ;


Not portable. Filling the memory block with all bits to zero may
produce an unexpected behaviour. For example, a pointer with all bits
to zero is not necessarely a NULL pointer. It's
implementation-dependent. Same problem with floating points. Please
read archives, this subject has been discussed ad-nauseam...

> 1). Do I have to allocate memory seperately for each individual nested
> pointer in the structure (i.e. hdr and subject?). I guess the answer is yes -
> but I just need to be sure (see question 3 below).


Yes. There is no magic in C. all mis explicit. If you want magic, build
you own 'constructor' function. A common approach.

> 2). How do I calculate the size (in bytes) of the structure MotherStruct - so
> that I can use a function like memcpy to copy this memory block to another
> memory block ?


You don't. The = operator does the job. Of course, the pointed blocks
are not copied. Once again, if you want magic, build your own 'copy'
function. If you insist (not typed pointers in a generic context), the
sizeof operator returns the sizeof of any typed object.

BTW, I feel a sort of design error... do you really need to copy such a
structure ? As far as possible, memory copies are to be avoided...

> 3). Finally, (this is related in a way to the first question). If I just call
> free on pMS is all the memory that was allocated freed (is the answer the
> same if I have to issue seperate calls to allocate memory to the individual
> nested pointers - i.e. will a single call to free(pMs) free any memory
> allocated to pointers nested within the structure - OR do I need to free each
> of the nested pointers before finally freeing the memory block pointed to by
> pMS ?


All what have been allocated must be explicitely freed. Once again, if
you want magic, build your own 'destructor'.

The RTL (standard C run-time library) uses such a approach with the
FILE object :

- Constructor : fopen()
- Destructor : fclose()

a good source of inspiration...

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++



Emmanuel Delahaye 09-24-2005 09:14 AM

Re: structures, structures and more structures (questions about nested structures)
 
Alfonso Morra wrote on 24/09/05 :
>>>2). How do I calculate the size (in bytes) of the structure MotherStruct

>>
>> sizeof(MotherStruct)

>
> This is the only answer that suprised me (in fact I don't believe its the
> correct answer).


It *is* the correct answer, but your structure being non linear (uses
pointers), it only concerns the structure itself (including the
pointers), **but not the pointed blocks**.

C is just straight and simple. Nothing is hidden or made in your back.

> I used to think this was the correct answer. But if you
> think about it, it can't be (at least, I can't see how it can be). How can
> sizeof know how much memory you have allocated for the char* (for example)?.
> The number returned by sizeof is independent of the size of the string that
> has been allocated for the member subject - so I think sizeof can be used for
> a simple structure with basic data types - whenever you have nested pointers,
> all bets are off. I think the correct way of doing this is to navigate the
> structure and sum up (sizeof(data_type) x number of data_type) all the way
> through all the members of the struct and any nested pointers - that makes
> sense from a logical point of view - but it would be great if someone could
> either confirm it or point me to a reference that shows me why my thinking is
> wrong.
>
> But thanks for the other two answers.


If you have pointed blocks with flexible size, you must keep a track of
the size. A common approach for a flexible string :

struct my_string
{
char *s;
size_t size;
};

a generic approach :

struct my_vector
{
void *p;
size_t size_of_an_element;
size_t number_of_elements;
};


--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"



Antonio Contreras 09-24-2005 12:28 PM

Re: structures, structures and more structures (questions about nested structures)
 
Alfonso Morra wrote:
> Hi,
>
> I have the ff data types :
>
> typedef enum {
> VAL_LONG ,
> VAL_DOUBLE ,
> VAL_STRING ,
> VAL_DATASET
> }ValueTypeEnum ;
>
> typedef union {
> long lval ;
> double fval ;
> char* sval ;
> void* ptr ;
> } Value ;
>
> typedef struct {
> int magic ;
> int version ;
> }Header ;
>
> typedef struct {
> char label[20] ;
> id int ;
> }Key ;
>
> typedef struct {
> Header *hdr ;
> char *subject ;
> int subject_len ;
> Key key ;
> ValueTypeEnum type ;
> Value value ;
> int text_len ;
> int size ;
> }MotherStruct ;
>
>
> If I have a variable declared as ff:
>
> MotherStruct *pMS = calloc(1,sizeof(MotherStruct*)) ;
>


<snip 3 questionz>

Leaving aside your questions, which have already been adressed by other
people, I think your call to calloc is ill written. Shouldn't it be:

MotherStruct *pMS = calloc(1, sizeof(MotherStruct));

???

You're allocating memory for a pointer to MotherStruct, not for a
MotherStruct. If you dereference pMS you'll invoke undefined behaviour.
Unless there's something I'm missing here.


Emmanuel Delahaye 09-24-2005 12:55 PM

Re: structures, structures and more structures (questions about nested structures)
 
Antonio Contreras wrote on 24/09/05 :
>> MotherStruct *pMS = calloc(1,sizeof(MotherStruct*)) ;


> Leaving aside your questions, which have already been adressed by other
> people, I think your call to calloc is ill written. Shouldn't it be:
>
> MotherStruct *pMS = calloc(1, sizeof(MotherStruct));
>
> You're allocating memory for a pointer to MotherStruct, not for a
> MotherStruct. If you dereference pMS you'll invoke undefined behaviour.
> Unless there's something I'm missing here.


Good catch.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"



Alfonso Morra 09-24-2005 05:26 PM

Re: structures, structures and more structures (questions about nestedstructures)
 


Emmanuel Delahaye wrote:

> Alfonso Morra wrote on 24/09/05 :
>
>> Hi,
>>
>> I have the ff data types :
>>
>> typedef enum {
>> VAL_LONG ,
>> VAL_DOUBLE ,
>> VAL_STRING ,
>> VAL_DATASET
>> }ValueTypeEnum ;
>>
>> typedef union {
>> long lval ;
>> double fval ;
>> char* sval ;
>> void* ptr ;
>> } Value ;
>>
>> typedef struct {
>> int magic ;
>> int version ;
>> }Header ;
>>
>> typedef struct {
>> char label[20] ;
>> id int ;
>> }Key ;
>>
>> typedef struct {
>> Header *hdr ;
>> char *subject ;
>> int subject_len ;
>> Key key ;
>> ValueTypeEnum type ;
>> Value value ;
>> int text_len ;
>> int size ;
>> }MotherStruct ;
>>
>> If I have a variable declared as ff:
>>
>> MotherStruct *pMS = calloc(1,sizeof(MotherStruct*)) ;

>
>
> Not portable. Filling the memory block with all bits to zero may produce
> an unexpected behaviour. For example, a pointer with all bits to zero is
> not necessarely a NULL pointer. It's implementation-dependent. Same
> problem with floating points. Please read archives, this subject has
> been discussed ad-nauseam...
>
>> 1). Do I have to allocate memory seperately for each individual nested
>> pointer in the structure (i.e. hdr and subject?). I guess the answer
>> is yes - but I just need to be sure (see question 3 below).

>
>
> Yes. There is no magic in C. all mis explicit. If you want magic, build
> you own 'constructor' function. A common approach.
>
>> 2). How do I calculate the size (in bytes) of the structure
>> MotherStruct - so that I can use a function like memcpy to copy this
>> memory block to another memory block ?

>
>
> You don't. The = operator does the job. Of course, the pointed blocks
> are not copied. Once again, if you want magic, build your own 'copy'
> function. If you insist (not typed pointers in a generic context), the
> sizeof operator returns the sizeof of any typed object.
>
> BTW, I feel a sort of design error... do you really need to copy such a
> structure ? As far as possible, memory copies are to be avoided...
>
>> 3). Finally, (this is related in a way to the first question). If I
>> just call free on pMS is all the memory that was allocated freed (is
>> the answer the same if I have to issue seperate calls to allocate
>> memory to the individual nested pointers - i.e. will a single call to
>> free(pMs) free any memory allocated to pointers nested within the
>> structure - OR do I need to free each of the nested pointers before
>> finally freeing the memory block pointed to by pMS ?

>
>
> All what have been allocated must be explicitely freed. Once again, if
> you want magic, build your own 'destructor'.
>
> The RTL (standard C run-time library) uses such a approach with the FILE
> object :
>
> - Constructor : fopen()
> - Destructor : fclose()
>
> a good source of inspiration...
>

Are you talking about ctors and dtors as in C++ ?



All times are GMT. The time now is 03:40 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.