473,396 Members | 2,092 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,396 software developers and data experts.

Baffling error with an array of class pointers

I'm a C++ novice and need help figuring out some odd behavior I've
encountered.

Here's the situation: I create a class and have its constructor store a
random number in a private "number" variable. The class also has a
"getNumber()" function that returns its stored number. A function in the
program creates five objects of this class and five pointers to these
objects, the latter of which are stored in a global array. When
"getNumber()" is called from the function that created these objects,
the correct number is returned. However, when called from a different
function, the returned number skyrockets! Here's an example from the
compiled program:

-Program output-
First display:
dummyArray[0]->getNumber(): 1
dummyArray[1]->getNumber(): 7
dummyArray[2]->getNumber(): 4
dummyArray[3]->getNumber(): 0
dummyArray[4]->getNumber(): 9

Second display:
dummyArray[0]->getNumber(): 4469728
dummyArray[1]->getNumber(): 4200022
dummyArray[2]->getNumber(): 2359128
dummyArray[3]->getNumber(): 4456499
dummyArray[4]->getNumber(): 2359104

An interesting fact is that when I omit the "dummyFunction2()" call in
the code below, I get a different result:

-Program output-
First display:
dummyArray[0]->getNumber(): 1
dummyArray[1]->getNumber(): 7
dummyArray[2]->getNumber(): 4
dummyArray[3]->getNumber(): 0
dummyArray[4]->getNumber(): 9

Second display:
dummyArray[0]->getNumber(): 1
dummyArray[1]->getNumber(): 7
dummyArray[2]->getNumber(): 4
dummyArray[3]->getNumber(): 4456499
dummyArray[4]->getNumber(): 2359104

Does anyone have an idea as to what's causing these strange occurrences?
Are there errors in my code? (See below!)

Here's the complete source code for the example program:

---CODE STARTS HERE---

#include <cstdlib>
#include <iostream>

using namespace std;

class Dummy{
public:
Dummy();
int getNumber();
private:
int number;
};

Dummy::Dummy(){
number=rand()%10;
}

int Dummy::getNumber(){
return number;
}

void dummyFunction1();
void dummyFunction2();
void dummyFunction3();
Dummy *dummyArray[5];

int main(){
dummyFunction1();
dummyFunction2();
dummyFunction3();
system("pause");
return 0;
}

void dummyFunction1(){
Dummy d1, d2, d3, d4, d5;
Dummy *d1Ptr=&d1, *d2Ptr=&d2, *d3Ptr=&d3, *d4Ptr=&d4, *d5Ptr=&d5;
dummyArray[0]=d1Ptr;
dummyArray[1]=d2Ptr;
dummyArray[2]=d3Ptr;
dummyArray[3]=d4Ptr;
dummyArray[4]=d5Ptr;

cout << "First display:\n";
cout << "dummyArray[0]->getNumber(): " << dummyArray[0]->getNumber()
<< "\n";
cout << "dummyArray[1]->getNumber(): " << dummyArray[1]->getNumber()
<< "\n";
cout << "dummyArray[2]->getNumber(): " << dummyArray[2]->getNumber()
<< "\n";
cout << "dummyArray[3]->getNumber(): " << dummyArray[3]->getNumber()
<< "\n";
cout << "dummyArray[4]->getNumber(): " << dummyArray[4]->getNumber()
<< "\n";
}

void dummyFunction2(){
cout << "\n";
}

void dummyFunction3(){
cout << "Second display:\n";
cout << "dummyArray[0]->getNumber(): " << dummyArray[0]->getNumber()
<< "\n";
cout << "dummyArray[1]->getNumber(): " << dummyArray[1]->getNumber()
<< "\n";
cout << "dummyArray[2]->getNumber(): " << dummyArray[2]->getNumber()
<< "\n";
cout << "dummyArray[3]->getNumber(): " << dummyArray[3]->getNumber()
<< "\n";
cout << "dummyArray[4]->getNumber(): " << dummyArray[4]->getNumber()
<< "\n\n";
}

---CODE ENDS HERE---

Thanks!
Scotty
Jun 8 '07 #1
3 1655
On Jun 7, 10:31 pm, Scotty <sco...@spamfree.4lifewrote:
I'm a C++ novice and need help figuring out some odd behavior I've
encountered.

Here's the situation: I create a class and have its constructor store a
random number in a private "number" variable. The class also has a
"getNumber()" function that returns its stored number. A function in the
program creates five objects of this class and five pointers to these
objects, the latter of which are stored in a global array. When
"getNumber()" is called from the function that created these objects,
the correct number is returned. However, when called from a different
function, the returned number skyrockets! Here's an example from the
compiled program:

-Program output-
First display:
dummyArray[0]->getNumber(): 1
dummyArray[1]->getNumber(): 7
dummyArray[2]->getNumber(): 4
dummyArray[3]->getNumber(): 0
dummyArray[4]->getNumber(): 9

Second display:
dummyArray[0]->getNumber(): 4469728
dummyArray[1]->getNumber(): 4200022
dummyArray[2]->getNumber(): 2359128
dummyArray[3]->getNumber(): 4456499
dummyArray[4]->getNumber(): 2359104
Welcome to the wonderful world of undefined behaviour. More below.
Does anyone have an idea as to what's causing these strange occurrences?
Are there errors in my code? (See below!)

Here's the complete source code for the example program:

---CODE STARTS HERE---

#include <cstdlib>
#include <iostream>

using namespace std;

class Dummy{
public:
Dummy();
int getNumber();
private:
int number;

};

Dummy::Dummy(){
number=rand()%10;

}

int Dummy::getNumber(){
return number;

}

void dummyFunction1();
void dummyFunction2();
void dummyFunction3();
Dummy *dummyArray[5];

int main(){
dummyFunction1();
dummyFunction2();
dummyFunction3();
system("pause");
return 0;

}

void dummyFunction1(){
Dummy d1, d2, d3, d4, d5;
Dummy *d1Ptr=&d1, *d2Ptr=&d2, *d3Ptr=&d3, *d4Ptr=&d4, *d5Ptr=&d5;
dummyArray[0]=d1Ptr;
dummyArray[1]=d2Ptr;
dummyArray[2]=d3Ptr;
dummyArray[3]=d4Ptr;
dummyArray[4]=d5Ptr;

cout << "First display:\n";
cout << "dummyArray[0]->getNumber(): " << dummyArray[0]->getNumber()
<< "\n";
cout << "dummyArray[1]->getNumber(): " << dummyArray[1]->getNumber()
<< "\n";
cout << "dummyArray[2]->getNumber(): " << dummyArray[2]->getNumber()
<< "\n";
cout << "dummyArray[3]->getNumber(): " << dummyArray[3]->getNumber()
<< "\n";
cout << "dummyArray[4]->getNumber(): " << dummyArray[4]->getNumber()
<< "\n";

}
^^^ Right here, objects d1, d2, d3, d4, and d5 go out of scope and are
destructed. The pointers to those objects, stored in dummyArray, no
longer point to valid objects.
void dummyFunction3(){
cout << "Second display:\n";
cout << "dummyArray[0]->getNumber(): " << dummyArray[0]->getNumber()
<< "\n";
Here you dereference one of those pointers. The moment you do that
the behaviour of your program is not well-defined: for you it prints
completely arbitrary values, but it's allowed to do literally
anything. It could crash. It could work perfectly. It could email
your inlaws and invite them to stay with you for the next year. It
could cause cancer in rodents.

You have a couple of options for making dummyArray usable from both
functions:

1. Initialize the d?Ptr variables in dummyFunction1 with 'new'
instead of with pointers to objects on the stack. You are then
responsible for cleaning up those objects with 'delete' when you're
done with them.
2. Store the actual objects in the array rather than pointers to the
objects, by declaring it as Dummy dummyArray[5]; and performing no
initialization in dummyFunction1.
3. Create and populate the array in main(), and pass it to the
dummyFunction1 and dummyFunction3 functions as an argument.

Owen

Jun 8 '07 #2
On Fri, 08 Jun 2007 05:31:31 GMT, Scotty <sc****@spamfree.4lifewrote
in comp.lang.c++:
I'm a C++ novice and need help figuring out some odd behavior I've
encountered.

Here's the situation: I create a class and have its constructor store a
random number in a private "number" variable. The class also has a
"getNumber()" function that returns its stored number. A function in the
program creates five objects of this class and five pointers to these
objects, the latter of which are stored in a global array. When
"getNumber()" is called from the function that created these objects,
the correct number is returned. However, when called from a different
function, the returned number skyrockets! Here's an example from the
compiled program:

-Program output-
First display:
dummyArray[0]->getNumber(): 1
dummyArray[1]->getNumber(): 7
dummyArray[2]->getNumber(): 4
dummyArray[3]->getNumber(): 0
dummyArray[4]->getNumber(): 9

Second display:
dummyArray[0]->getNumber(): 4469728
dummyArray[1]->getNumber(): 4200022
dummyArray[2]->getNumber(): 2359128
dummyArray[3]->getNumber(): 4456499
dummyArray[4]->getNumber(): 2359104

An interesting fact is that when I omit the "dummyFunction2()" call in
the code below, I get a different result:

-Program output-
First display:
dummyArray[0]->getNumber(): 1
dummyArray[1]->getNumber(): 7
dummyArray[2]->getNumber(): 4
dummyArray[3]->getNumber(): 0
dummyArray[4]->getNumber(): 9

Second display:
dummyArray[0]->getNumber(): 1
dummyArray[1]->getNumber(): 7
dummyArray[2]->getNumber(): 4
dummyArray[3]->getNumber(): 4456499
dummyArray[4]->getNumber(): 2359104

Does anyone have an idea as to what's causing these strange occurrences?
Are there errors in my code? (See below!)

Here's the complete source code for the example program:

---CODE STARTS HERE---

#include <cstdlib>
#include <iostream>

using namespace std;

class Dummy{
public:
Dummy();
int getNumber();
private:
int number;
};

Dummy::Dummy(){
number=rand()%10;
}

int Dummy::getNumber(){
return number;
}

void dummyFunction1();
void dummyFunction2();
void dummyFunction3();
Dummy *dummyArray[5];

int main(){
dummyFunction1();
dummyFunction2();
dummyFunction3();
system("pause");
return 0;
}

void dummyFunction1(){
Dummy d1, d2, d3, d4, d5;
In the line above you define five dummy objects. Space is allocated
for them and their constructors executed. These are local objects in
this function, and have automatic storage duration. They live until
the function exits.
Dummy *d1Ptr=&d1, *d2Ptr=&d2, *d3Ptr=&d3, *d4Ptr=&d4, *d5Ptr=&d5;
dummyArray[0]=d1Ptr;
dummyArray[1]=d2Ptr;
dummyArray[2]=d3Ptr;
dummyArray[3]=d4Ptr;
dummyArray[4]=d5Ptr;

cout << "First display:\n";
cout << "dummyArray[0]->getNumber(): " << dummyArray[0]->getNumber()
<< "\n";
cout << "dummyArray[1]->getNumber(): " << dummyArray[1]->getNumber()
<< "\n";
cout << "dummyArray[2]->getNumber(): " << dummyArray[2]->getNumber()
<< "\n";
cout << "dummyArray[3]->getNumber(): " << dummyArray[3]->getNumber()
<< "\n";
cout << "dummyArray[4]->getNumber(): " << dummyArray[4]->getNumber()
<< "\n";
Here at the end of the function, the five dummy objects you created at
the beginning of the function go out of scope. The space the occupied
is released.
}

void dummyFunction2(){
cout << "\n";
}

void dummyFunction3(){
cout << "Second display:\n";
cout << "dummyArray[0]->getNumber(): " << dummyArray[0]->getNumber()
<< "\n";
cout << "dummyArray[1]->getNumber(): " << dummyArray[1]->getNumber()
<< "\n";
cout << "dummyArray[2]->getNumber(): " << dummyArray[2]->getNumber()
<< "\n";
cout << "dummyArray[3]->getNumber(): " << dummyArray[3]->getNumber()
<< "\n";
cout << "dummyArray[4]->getNumber(): " << dummyArray[4]->getNumber()
<< "\n\n";
}

When dummyFunction1() returns, dummyArray[] is left containing
pointers to objects that do not exist anymore. Attempting to
reference an object after its lifetime ends generates undefined
behavior. Printing some random numbers is one possible consequence of
undefined behavior.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Jun 8 '07 #3
Scotty <sc****@spamfree.4lifewrote in news:TQ5ai.18258$Ut6.1537
@newsread1.news.pas.earthlink.net:
I'm a C++ novice and need help figuring out some odd behavior I've
encountered.
[snip description of objects appearing to change values]
>
Here's the complete source code for the example program:

---CODE STARTS HERE---

#include <cstdlib>
#include <iostream>

using namespace std;

class Dummy{
public:
Dummy();
int getNumber();
private:
int number;
};

Dummy::Dummy(){
number=rand()%10;
}

int Dummy::getNumber(){
return number;
}

void dummyFunction1();
void dummyFunction2();
void dummyFunction3();
Dummy *dummyArray[5];

int main(){
dummyFunction1();
dummyFunction2();
dummyFunction3();
system("pause");
return 0;
}

void dummyFunction1(){
Dummy d1, d2, d3, d4, d5;
OK, you create 5 local Dummy objects. These will go out of scope at the
end of this function.
Dummy *d1Ptr=&d1, *d2Ptr=&d2, *d3Ptr=&d3, *d4Ptr=&d4, *d5Ptr=&d5;
Now you take the addresses of all of those object. Minor alarm bells are
going off in my head. These are pointers to objects that will be
destroyed when this function ends. There's a potential for Undefined
Behaviour. Depends on what you do with these pointers.
dummyArray[0]=d1Ptr;
dummyArray[1]=d2Ptr;
dummyArray[2]=d3Ptr;
dummyArray[3]=d4Ptr;
dummyArray[4]=d5Ptr;
Now you're sticking those pointers into a global array. Really big alarm
bells are going off now. The potential of the program invoking Undefined
Behaviour just skyrocketed. Since these pointers are now in a global
array, other parts of the program are going to have access to them. And
if anybody attempts to dereference them after this function ends,
Undefined Behaviour.
>
cout << "First display:\n";
cout << "dummyArray[0]->getNumber(): " << dummyArray[0]->getNumber
()
<< "\n";
cout << "dummyArray[1]->getNumber(): " << dummyArray[1]->getNumber
()
<< "\n";
cout << "dummyArray[2]->getNumber(): " << dummyArray[2]->getNumber
()
<< "\n";
cout << "dummyArray[3]->getNumber(): " << dummyArray[3]->getNumber
()
<< "\n";
cout << "dummyArray[4]->getNumber(): " << dummyArray[4]->getNumber
()
<< "\n";
Those 5 dummy objects now go out of scope, and that global array still
contains the pointers to them. I'm almost certain that Undefined
Behaviour is going to happen sometime in the future.
}

void dummyFunction2(){
cout << "\n";
}

void dummyFunction3(){
cout << "Second display:\n";
cout << "dummyArray[0]->getNumber(): " << dummyArray[0]->getNumber
()
<< "\n";
And kaboom. It's not a potential Undefined Behaviour anymore. This code
has invoked Undefined Behaviour. The object that dummyArray[0] points to
no longer exists. (Same goes for the rest of the array)
cout << "dummyArray[1]->getNumber(): " << dummyArray[1]->getNumber
()
<< "\n";
cout << "dummyArray[2]->getNumber(): " << dummyArray[2]->getNumber
()
<< "\n";
cout << "dummyArray[3]->getNumber(): " << dummyArray[3]->getNumber
()
<< "\n";
cout << "dummyArray[4]->getNumber(): " << dummyArray[4]->getNumber
()
<< "\n\n";
}

---CODE ENDS HERE---

Thanks!
Scotty
Jun 8 '07 #4

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

Similar topics

3
by: michi | last post by:
Hello, I need to initialize a 2 dimensional square arrays of structures. The size of array I get from the user. I can do one-dimensional array, but I don't know how to specify the size of array...
6
by: Stephane Vollet | last post by:
Can someone tell me what's wrong with my code here? When compiling, it says : error C2143: syntax error : missing ';' before '*' error C2501: 'Tcase' : missing storage-class or type specifiers...
11
by: westplastic | last post by:
This one is driving me insane. The script works perfect on Firefox, but Internet Explorer keeps complaining about "Error Object Expected" and stuff like that. I've run it through Firefox's Java...
2
by: Double Echo | last post by:
Hi, Forgive me if I ask a dumb question, I'm new to classes and object programming with PHP, and cannot figure out what the problem is with this class. Maybe I have overlooked something but...
3
by: Bilgehan.Balban | last post by:
Hi, How do I declare an array of function pointers and assign each element of the array with public member functions of a class? Is it possible that the array is not a member of the class? ...
23
by: sandy | last post by:
I need (okay, I want) to make a dynamic array of my class 'Directory', within my class Directory (Can you already smell disaster?) Each Directory can have subdirectories so I thought to put these...
17
by: =?Utf-8?B?U2hhcm9u?= | last post by:
Hi Gurus, I need to transfer a jagged array of byte by reference to unmanaged function, The unmanaged code should changed the values of the array, and when the unmanaged function returns I need...
2
by: StevenChiasson | last post by:
For the record, not a student, just someone attempting to learn C++. Anyway, the problem I'm having right now is the member function detAddress, of object controller. This is more or less, your...
5
by: Immortal Nephi | last post by:
I would like to design an object using class. How can this class contain 10 member functions. Put 10 member functions into member function pointer array. One member function uses switch to call...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.