for some reason, after creating an object in main func., the destructor gets called right away, isn't it supposed to get called only when main finishes? thanks
code:
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
class check{ //create class check
public:
string m_bank_name;
int m_check_number;
int m_branch_number;
char* m_check_sum;
check ( string bank_name, int check_number, int branch_number, char* check_sum){
int a_size = (strlen(check_sum)+1);
m_check_sum = new char[a_size]();
for (int i=0;i<a_size;i++)
{
m_check_sum[i]=check_sum[i];
}
m_bank_name= bank_name;
m_check_number = check_number;
m_branch_number = branch_number;
}
~check (){
delete [] m_check_sum;
cout<<"deleted!"<<endl;
}
};
void main(){
check ob1= check("poalim",809877,12,"4578");
cout<<ob1.m_check_sum<<endl;
getchar();
}
This expression
check("poalim",809877,12,"4578")
creates a temporary object that gets destroyed right after the full expression (;)
Before being destroyed, it is copied to ob1, which is destroyed at the end of the main function.
Perhaps you meant to write
int main(){ //note the correct return type of main
check ob1("poalim",809877,12,"4578"); //direct constructor call
cout<<ob1.m_check_sum<<endl;
getchar();
}
I really suggest that you should read a good book on C++ fundamentals.
Related
#include <iostream>
using namespace std;
class MyStaticClass{
public:
static int value;
MyStaticClass(){
value++;
}
~MyStaticClass(){}
};
int MyStaticClass::value;
void main(){
MyStaticClass::value = 0;
for (int i = 0; i<9; i++)
MyStaticClass *c = new MyStaticClass();
cout << MyStaticClass::value;
system("pause");
}
Please explain me why the result is 9, and when replace MyStaticClass *c = new MyStaticClass() with MyStaticClass c() the result changes to 0? Finally what is the meaning of int MyStaticClass::value;, why when i delete that line the compiler shows error? Thanks everyone!
The line int MyStaticClass::value; tells the compiler to reserve storage for the static variable value. If you don't do that then the linker will fail.
The result is 9 since the for loop body executes 9 times: you are creating 9 new instances of MyStaticClass (which isn't really a static class, it just has a static member). Note that you ought to delete all these objects else your program leaks memory.
MyStaticClass c(); declares a function prototype for a function c that takes no parameters and returns a MyStaticClass: it does not create an object. This is nicknamed the most vexing parse. Since no object is created, value stays at 0. It would have been a different matter had you written MyStaticClass c;
So I'm trying to use get/set functions, and I'm having a problem changing the default Astring using the set fuction. Program crashes after when I try to run with this:
#include <iostream>
#include <string>
using namespace std;
class Example{
private:
string m_Astring;
public:
Example()
{
m_Astring="123456789012";
}
string setAstring(string Astring){m_Astring=Astring;}
string getAstring(){return m_Astring;}
};
int main(){
Example test;
test.setAstring("250687354221");
cout<<test.getAstring()<<endl;
return 0;
}
The problem is here:
string setAstring(string Astring){m_Astring=Astring;}
^^^^^^ ^^^^
return a string no return of string
Your program crashes because you never returned anything from this function, and that is undefined.
(I suspect that the crash occurs when destroying the non-existent return value, but I haven't confirmed this.)
Both sections of code below are drastically simplified, isolated versions of my actual code. The examples are just big enough to reproduce the problem. The first section of code below works fine. The section section is an attempt to begin to make it part of a class. I'm trying to take tiny steps since small modifications to something like the struct shown below require lots of changes throughout the code which is full of pointers, pointer to pointers and references which all involve this struct. Can you tell me why the second section of code throws a stack overflow within it's constructor and what small changes can be made to fix it?
Working code:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
const int maxSize = 3;
struct Item{
int count;
Item *items[maxSize + 1];
};
void foo()
{
Item *p;
p = new Item();
p->count = 2;
cout << p->count << endl;
}
int main(int argc, char *argv[])
{
foo();
return 0;
}
Attempt to very gradually modify the code as a whole toward becoming a class:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
int maxSize = 3;
struct Item{
int count;
Item *items;
Item()
{
items = new Item[maxSize + 1]; // stack overflow
}
};
void Initialize(int size)
{
maxSize = size;
}
void foo()
{
Item *p;
p = new Item();
p->count = 2;
cout << p->count << endl;
}
int main(int argc, char *argv[])
{
Initialize(5);
foo();
return 0;
}
The first call to construct a Item calls new Item[maxSize+1], which calls the default constructor, which calls new Item[maxSize+1], which calls the default construct, and so on until you reach stack overflow.
All the answers are right. I want to suggest a solution for you:
Instead of initializing the array within the ctor, you could implement an initialization method like
init(int maxSize) {
items = new Item[maxSize + 1];
}
that you can call after having constructed the object. This should avoid the stack overflow. In general, you should avoid to place instances of an object inside the object itself. Its better to use Collections of the Item
List<Item>, std::vector<Item>, ...
It is because in working version you have reference to an array of object, but not actual object of Items. In second version, you are creating objects by using keyword new. So, in second version in constructor it will call itself! It will call it's own constructor infinite times. Hence, you see runtime exception stackoverflow :)
Above posters are right. Within the constructor of Item you create items (by creating an array). So the ctor is again called, which creates more items, which .... This is more or less an infinite loop which eats up your stack.
Either stick with the references or use a collection like List - so you can add the items later on dynamically.
I'm new to shared_ptr's and I'm trying to figure out the exact functionality of the .reset() function.
#include <memory>
#include <stdio>
using namespace std;
class SomeClass{};
int main()
{
shared_ptr<SomeClass> sp (nullptr);
//do some stuff, sp now has 10 co-owners
cout << sp.use_count << endl;
sp.reset();
cout << sp.use_count << endl;
return 0;
}
Would output
10
0
So since I used the reset function are all instances deleted from memory? As in, have I just eliminated any possible memory leaks with sp? Obviously this was a toy example that I quickly made up, sorry if it has any errors.
Follow up situation:
shared_ptr<SomeClass> returnThis() {
shared_ptr<SomeClass> someObject(new SomeClass(/*default constructor for example*/) );
return someObject;
}
somehere in main:
shared_ptr<SomeClass> mainObject;
mainObject = returnThis();
Does mainObject have a use count of 2 because someObject was created in a function but never cleared? Or is it one and the clean-up is done automatically when returning the value?
When you use .reset(), you are eliminating one owner of the pointer, but all of the other owners are still around. Here is an example:
#include <memory>
#include <cstdio>
class Test { public: ~Test() { std::puts("Test destroyed."); } };
int main()
{
std::shared_ptr<Test> p = std::make_shared<Test>();
std::shared_ptr<Test> q = p;
std::puts("p.reset()...");
p.reset();
std::puts("q.reset()...");
q.reset();
std::puts("done");
return 0;
}
The program output:
p.reset()...
q.reset()...
Test destroyed.
done
Note that p and q are both owners of the object, and once both p and q are reset, then the instance is destroyed.
No.
The whole purpose of shared_ptr is that you cannot delete it from one place if someone is using it in another. shared_ptr::reset() just decreases use_count by one and replaces its object by nullptr.
The .reset() method only applies to the object it's called upon.
It just replaces the pointer that variable is holding.
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
class newclass
{
public:
string *Date;
void show(){ cout << this->Date;}
};
int main()
{
newclass *n = new newclass;
n->Date = new string ;
n->Date.assign("hello"); // get an error on this line
n->show();
return 0;
}
Can Somebody please explain me how this works?. I am new to this.
n->Date->assign("hello") because n->Date is a pointer, so you must dereference it before calling a function on it.
Please look at this SO Question for a detailed explanation of the syntax.
It looks like you're applying idioms from another language. In C++ you should avoid pointers whenever possible, replaced by member or local variables. Your code in that case would look like this:
class newclass
{
public:
string Date;
void show(){ cout << this->Date;}
};
int main() {
newclass n;
n.Date.assign("hello");
n.show();
return 0;
}
You've got a few problems here, let's go over them one at a time:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
class newclass
{
public:
// This is a pointer to a std::string, that doesn't appear to
// be allocated. From this small example, you don't really need
// a pointer at all:
// string *Date;
// now that this object isn't a pointer, you can use dot syntax
// to access its member functions
string Date;
void show()
{
// accessing date through this-> is not necessary
// here. You can simply use Date. However since this
// doesn't cause any specific problems I mention it only
// as informational
cout << this->Date;
}
};
int main()
{
newclass *n = new newclass;
// This is bad practice, you generally shouldn't be allocating
// objects within a class outside of that class's implementation.
// this would better be done in the newclass constructor.
// n->Date = new string ;
// Since we replaced the pointer to string object Date in newclass
// and replaced it with an automatic string object, this line will
// now work as written.
n->Date.assign("hello"); // get an error on this line
n->show();
// At this point your program will exit, and newclass is shown as
// a memory leak. While the OS will reclaim this memory at application
// exit, its good to get used to managing the lifetime of your objects
// appropriate. This has do be deleted, or better yet wrapped in a smart
// pointer
delete n;
return 0;
}
To provide an example that is similar to your original question, let's take the following code:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <memory>
using namespace std;
class newclass
{
public:
// auto_ptr is a smart pointer class that
// wraps a dynamically allocated object and
// provides cleanup for it when it goes out
// of scope. So when our class goes out of
// scope the Date object will be cleaned up
// for us
auto_ptr<string> Date;
// this is the constructor of the newclass object
// its called anytime a newclass object is instantiated
// we use the initializer list to allocate the Date object
newclass() : Date(new string)
{
}
// a mutator for setting the Date object (promotes encapsulation)
void set_date(const std::string& val)
{
// necessary to dereference to get at the date object
(*Date) = val;
}
void show() { cout << this->Date; }
};
int main()
{
// note the use of an auto_ptr here for automatic cleanup
auto_ptr<newclass> n(new newclass);
// use our mutator method to set the date
n->set_date("hello");
n->show();
return 0;
}
Date is itself a pointer to string, you will need to dereference it as well:
n->Date->assign("hello");
newclass *n = new newclass;
n->Date = new string ;
n->Date->assign("hello"); // use -> when accessing a member of a pointer
n->show();