473,320 Members | 1,857 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Problem with class type in static instance of struct

We had a strange problem in a large project with the use of a string class
in a static instance of a struct.
I managed to reproduce the exactly same problem in a very short program (see
below).
When the constant SHORT_STRING_SIZE_LIMIT is set to 0, the program works as
expected and outputs the string "+". When it is set to 7, it outputs garbage
(a part of a non-initialized storage area).
We are using gcc version 3.3 on SuSE Linux.

#include <iostream>
using namespace std;

const unsigned int SHORT_STRING_SIZE_LIMIT = 0;
//const unsigned int SHORT_STRING_SIZE_LIMIT = 7;
// String
class ----------------------------------------------------------------
class String
{
public:
String(const char* s);
friend ostream& operator<< (ostream& os, const String& sStr);

private:
char* allocate();

char m_cShortString[SHORT_STRING_SIZE_LIMIT + 1];
unsigned int m_uiCapa;
unsigned int m_uiSize;
char* m_p;
};

String::String(const char* s)
{
if (s == NULL) {
m_p = allocate();
m_p[0] = '\0';
return;
}
m_uiSize = strlen(s);
m_p = allocate();
strcpy(m_p, s);
}

char* String::allocate()
{
char* p;
if (m_uiSize <= SHORT_STRING_SIZE_LIMIT) {
m_uiCapa = SHORT_STRING_SIZE_LIMIT;
p = m_cShortString;
} else {
m_uiCapa = m_uiSize;
p = new char[m_uiCapa + 1];
}
return p;
}

ostream& operator<< (ostream& os, const String& sStr)
{
os << sStr.m_p;
return os;
}
// End of String
class ---------------------------------------------------------
struct Operators
{
String m_sOperator;
};
static Operators operators= {"+"};
int main()
{
cout << operators.m_sOperator << endl;
}
Jul 22 '05 #1
11 1655
Robert Sturzenegger wrote:
We had a strange problem in a large project with the use of a string class
in a static instance of a struct.
I managed to reproduce the exactly same problem in a very short program (see
below).
When the constant SHORT_STRING_SIZE_LIMIT is set to 0, the program works as
expected and outputs the string "+". When it is set to 7, it outputs garbage
(a part of a non-initialized storage area).
We are using gcc version 3.3 on SuSE Linux.
Well, looks like a bug in the compiler. Did you use the debugger to find
out what's wrong?
[...]


V
Jul 22 '05 #2

"Robert Sturzenegger" <no****@nowhere.net> wrote in message news:cq**********@news.hispeed.ch...
We had a strange problem in a large project with the use of a string class
in a static instance of a struct.
I managed to reproduce the exactly same problem in a very short program (see
below).
When the constant SHORT_STRING_SIZE_LIMIT is set to 0, the program works as
expected and outputs the string "+". When it is set to 7, it outputs garbage
(a part of a non-initialized storage area).
We are using gcc version 3.3 on SuSE Linux.

#include <iostream>
using namespace std;

const unsigned int SHORT_STRING_SIZE_LIMIT = 0;
file://const unsigned int SHORT_STRING_SIZE_LIMIT = 7;
// String
class ----------------------------------------------------------------
class String
{
public:
String(const char* s);
friend ostream& operator<< (ostream& os, const String& sStr);

private:
char* allocate();

char m_cShortString[SHORT_STRING_SIZE_LIMIT + 1];
unsigned int m_uiCapa;
unsigned int m_uiSize;
char* m_p;
};

String::String(const char* s)
{
if (s == NULL) {
m_p = allocate();
m_p[0] = '\0';
return;
}
m_uiSize = strlen(s);
m_p = allocate();
strcpy(m_p, s);
}

char* String::allocate()
{
char* p;
if (m_uiSize <= SHORT_STRING_SIZE_LIMIT) {
m_uiCapa = SHORT_STRING_SIZE_LIMIT;
p = m_cShortString;
} else {
m_uiCapa = m_uiSize;
p = new char[m_uiCapa + 1];
}
return p;
}

ostream& operator<< (ostream& os, const String& sStr)
{
os << sStr.m_p;
return os;
}
// End of String
class ---------------------------------------------------------
struct Operators
{
String m_sOperator;
};
static Operators operators= {"+"};
int main()
{
cout << operators.m_sOperator << endl;
}


I had no problems with this program using
DigitalMars (have purchased CD) in Win2K
Pro SP4 - in both cases the output is "+"

Alan
Jul 22 '05 #3
jd
Le Mon, 27 Dec 2004 17:39:24 +0100, Robert Sturzenegger a écrit*:
We had a strange problem in a large project with the use of a string class
in a static instance of a struct.
I managed to reproduce the exactly same problem in a very short program (see
below).
When the constant SHORT_STRING_SIZE_LIMIT is set to 0, the program works as
expected and outputs the string "+". When it is set to 7, it outputs garbage
(a part of a non-initialized storage area).
We are using gcc version 3.3 on SuSE Linux.

#include <iostream>
using namespace std;

const unsigned int SHORT_STRING_SIZE_LIMIT = 0;
//const unsigned int SHORT_STRING_SIZE_LIMIT = 7;
// String
class ----------------------------------------------------------------
class String
{
public:
String(const char* s);
friend ostream& operator<< (ostream& os, const String& sStr);

private:
char* allocate();

char m_cShortString[SHORT_STRING_SIZE_LIMIT + 1];
unsigned int m_uiCapa;
unsigned int m_uiSize;
char* m_p;
};

String::String(const char* s)
{
if (s == NULL) {
m_p = allocate();
m_p[0] = '\0';
return;
}
m_uiSize = strlen(s);
m_p = allocate();
strcpy(m_p, s);
}

char* String::allocate()
{
char* p;
if (m_uiSize <= SHORT_STRING_SIZE_LIMIT) {
m_uiCapa = SHORT_STRING_SIZE_LIMIT;
p = m_cShortString;
} else {
m_uiCapa = m_uiSize;
p = new char[m_uiCapa + 1];
}
return p;
}

ostream& operator<< (ostream& os, const String& sStr)
{
os << sStr.m_p;
return os;
}
// End of String
class ---------------------------------------------------------
struct Operators
{
String m_sOperator;
};
static Operators operators= {"+"};
int main()
{
cout << operators.m_sOperator << endl;
}


This doesn't look a compiler error for me.
Your Operators struct simply doesn't use the constructors you have
providen for your String class.

Jul 22 '05 #4
Robert Sturzenegger wrote:
We had a strange problem in a large project with the use of a string class
in a static instance of a struct.
I managed to reproduce the exactly same problem in a very short program (see
below).
When the constant SHORT_STRING_SIZE_LIMIT is set to 0, the program works as


Your class needs a copy constructor (and a assignment operator and a destructor,
and perhaps even a default constructor).

The problem is that when the limit is set to zero, the implicitly defined
copy constructor copies the pointer but since it points to memory you never
free, the thing works OK. In your case where you have the small string
support, the pointer is copied, but it points to the array of a temporary
object whose lifetime expires (and obviously gets written over).

Jul 22 '05 #5
Muk
strcpy(m_p, s);

Before you do this make sure the src string s is null terminated (\0).
In your case it looks like it is not ("+"). Now when
SHORT_STRING_SIZE_LIMIT = 7, you are copying into char
m_cShortString[8]; Since the dest array m_cShortString may not have \0
at each index, the string is basically not null terminated. This may
cause os << sStr.m_p to print vague results since it does not know the
end of the array (no \0 at end). Make sure all your arrays and strings
are null terminated, especially when using C style functions like
strcpy. When SHORT_STRING_SIZE_LIMIT = 0 you are creating new
allocation using new char[m_uiCapa + 1] and it looks like the resultant
memory had nulls in it and hence it worked.

Jul 22 '05 #6
"Muk" <rs******@hotmail.com> wrote...
strcpy(m_p, s);

Before you do this make sure the src string s is null terminated (\0).
In your case it looks like it is not ("+"). [...]


Every string literal is null-terminated, see 2.13.4p4.
Jul 22 '05 #7

"Ron Natalie" <ro*@sensor.com> wrote in message
news:41***********************@news.newshosting.co m...
Robert Sturzenegger wrote:
We had a strange problem in a large project with the use of a string
class
in a static instance of a struct.
I managed to reproduce the exactly same problem in a very short program
(see
below).
When the constant SHORT_STRING_SIZE_LIMIT is set to 0, the program works
as


Your class needs a copy constructor (and a assignment operator and a
destructor,
and perhaps even a default constructor).

The problem is that when the limit is set to zero, the implicitly defined
copy constructor copies the pointer but since it points to memory you
never
free, the thing works OK. In your case where you have the small string
support, the pointer is copied, but it points to the array of a temporary
object whose lifetime expires (and obviously gets written over).


What I posted, is only a small extract of the class. As a matter of course
the class does have a default ctor, several other ctors, a copy ctor and a
dtor. But these do not affect the behaviour in question and that's why I
leaved them out.

Jul 22 '05 #8

"jd" <zi******@free.fr> schrieb im Newsbeitrag
news:pa****************************@free.fr...
Le Mon, 27 Dec 2004 17:39:24 +0100, Robert Sturzenegger a écrit :
We had a strange problem in a large project with the use of a string class in a static instance of a struct.
I managed to reproduce the exactly same problem in a very short program (see below).
When the constant SHORT_STRING_SIZE_LIMIT is set to 0, the program works as expected and outputs the string "+". When it is set to 7, it outputs garbage (a part of a non-initialized storage area).
We are using gcc version 3.3 on SuSE Linux.

#include <iostream>
using namespace std;

const unsigned int SHORT_STRING_SIZE_LIMIT = 0;
//const unsigned int SHORT_STRING_SIZE_LIMIT = 7;
// String
class ----------------------------------------------------------------
class String
{
public:
String(const char* s);
friend ostream& operator<< (ostream& os, const String& sStr);

private:
char* allocate();

char m_cShortString[SHORT_STRING_SIZE_LIMIT + 1];
unsigned int m_uiCapa;
unsigned int m_uiSize;
char* m_p;
};

String::String(const char* s)
{
if (s == NULL) {
m_p = allocate();
m_p[0] = '\0';
return;
}
m_uiSize = strlen(s);
m_p = allocate();
strcpy(m_p, s);
}

char* String::allocate()
{
char* p;
if (m_uiSize <= SHORT_STRING_SIZE_LIMIT) {
m_uiCapa = SHORT_STRING_SIZE_LIMIT;
p = m_cShortString;
} else {
m_uiCapa = m_uiSize;
p = new char[m_uiCapa + 1];
}
return p;
}

ostream& operator<< (ostream& os, const String& sStr)
{
os << sStr.m_p;
return os;
}
// End of String
class ---------------------------------------------------------
struct Operators
{
String m_sOperator;
};
static Operators operators= {"+"};
int main()
{
cout << operators.m_sOperator << endl;
}


This doesn't look a compiler error for me.
Your Operators struct simply doesn't use the constructors you have
providen for your String class.


Yes, it does! I also tried with cout in the ctor. The ctor is run in both
cases.
Jul 22 '05 #9
Robert Sturzenegger wrote:


What I posted, is only a small extract of the class. As a matter of course
the class does have a default ctor, several other ctors, a copy ctor and a
dtor. But these do not affect the behaviour in question and that's why I
leaved them out.

Perhaps you should put them back in, because it sure as hell makes the
example WRONG without them.

What does your copy constructor look like?
Jul 22 '05 #10
Ron Natalie wrote:
Robert Sturzenegger wrote:


What I posted, is only a small extract of the class. As a matter of
course the class does have a default ctor, several other ctors, a copy
ctor and a dtor. But these do not affect the behaviour in question and
that's why I leaved them out.

Perhaps you should put them back in, because it sure as hell makes the
example WRONG without them.


Why is it WRONG? We're not discussing the merits of dynamic memory
allocation and the rule of three here. Is there any part to the code
presented that exhibits undefined behaviour? If yes, would you please
elaborate?
What does your copy constructor look like?


Why do you care? There is no d-tor that attempts to delete the pointer.
There is no copying taking place in this code, AFAICS. Or is there?
The question is about the code posted. It _is_ complete and is known
to exhibit the behaviour described, but only when compiled with g++
(I did check with VC++, and it worked as expected). Why does it matter
what the _other_ code looks like?
Jul 22 '05 #11

"Ron Natalie" <ro*@sensor.com> schrieb im Newsbeitrag
news:41***********************@news.newshosting.co m...
Robert Sturzenegger wrote:


What I posted, is only a small extract of the class. As a matter of course the class does have a default ctor, several other ctors, a copy ctor and a dtor. But these do not affect the behaviour in question and that's why I
leaved them out.

Perhaps you should put them back in, because it sure as hell makes the
example WRONG without them.

What does your copy constructor look like?


Would you prefer to see 3786 lines of code here. As I said, this sample code
is about the minumum which is necessary, to show the behavior in question.
Every bit of code NOT shown here does NOT affect this behaviour.
In the meantime, I rather think that what is missing, are ctors and copy
ctor of the struct.
Jul 22 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Neil Zanella | last post by:
Hello, I would like to know whether it is possible to define static class methods and data members in Python (similar to the way it can be done in C++ or Java). These do not seem to be mentioned...
8
by: Pent | last post by:
Hi All, Why is this code valid? How can the static ctor be used? It doesn't act as class ctor at all. struct A { static A() { } }
2
by: Andrew G. J. Fung | last post by:
Can anyone please explain to me why the code below throws an exception? It seems to occur when deserializing an instance of a subclass, whose base class holds a struct, where said struct holds an...
9
by: thomson | last post by:
Hi all, Would you please explain me where will be the heap stored if it is declared inside the Class, As class is a reference type, so it gets stored on the heap, but struct is a value...
2
by: ajikoe | last post by:
Hi, I tried to follow the example in swig homepage. I found error which I don't understand. I use bcc32, I already include directory where my python.h exist in bcc32.cfg. /* File : example.c...
4
by: PSL | last post by:
Hi, I am going through the training C# For Programmers made by TestOut and like the presentation. The only problem is that this tutorial has a nastie bug that renders this software practically...
8
by: Per Bull Holmen | last post by:
Hey Im new to c++, so bear with me. I'm used to other OO languages, where it is possible to have class-level initialization functions, that initialize the CLASS rather than an instance of it....
6
by: per9000 | last post by:
An interesting/annoying problem. I created a small example to provoke an exception I keep getting. Basically I have a C-struct (Container) with a function-pointer in it. I perform repeated calls...
7
by: pallav | last post by:
I'm having some trouble with my copy constructor. I've tried using gdb to find the bug, but it seg faults in the destructor. I'm not able to see what I'm doing wrong. Since I'm using pointers, I...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.