Whenever i run the commented part of the constructor money the program crashes.
When i compile it, it does not throw any error as well.
Can someone tell me what is happening?
Also i am trying to implement the vending machine problem here.
i have removed some parts of the code which are working properly.
#include <iostream>
using namespace std;
class money
{
public :
int *max;
int *accepted_values = new int[10];
bool present;
int *deposited;
int i;
money()
{
}
money(int *a, int how_many)
{
//*max = how_many;
// for (i=0; i<how_many; i++)
// {
// accepted_values[i] = a[i];
// }
//*deposited = 0;
present = false;
}
};
class Vending_machine
{
public :
money *coins = new money(accepted_coins, 5);
//money *coins = new money();
int *amount_deposited = new int;
Vending_machine()
{
cout<<"Cool";
}
~Vending_machine()
{
delete amount_deposited;
}
};
int main()
{
Vending_machine a;
}
You are dereferencing the int pointers int *max and int *depositedin your constructor, without assigning a proper memory address first.
This will always crash, since it's undefined behaviour.
int* myPointer;
*myPointer = 10; // crashes
A pointer has always to point to a valid address first, before you can use it.
This could be the address of another variable:
int myInt;
int *myPointer = &myInt;
*myPointer = 10; // doesn't crash - myInt now is 10.
or it could be dynamically allocated and released.
int* myPointer = new int;
But in that case you'll have to take care that the memory is released once you are done.
delete myPointer;
A better solution is to use std::unique_ptr<>, which takes care of releasing its pointer on destruction.
But the best solution is not to use pointers at all, if they are not really necessary - especially if you don't know very exactly how pointers work. I assume in your example you could avoid pointers completely.
Related
Im fairly new to C++.
So I learned that new allocates memory and returns a pointer of my datatype. But can I use this in a function and return the pointer? If so then where should I place the delete operator?
Is the following code legal?
int *makeArray(int size)
{
int *result = new int[size];
delete[] result;
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... */
return 0;
}
It is compiling and working but logically it makes no sense because I deleted my array.
So I tried the following:
int *makeArray(int size)
{
int *result = new int[size];
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... do some stuff with pointer */
delete[] pointer;
return 0;
}
Is this safe or does it cause a memory leak? Is there a better way of returning the pointer?
I tried both versions and they are compiling and working but I'm sure at least one of them if not both are unsafe.
Is the following code legal?
int *makeArray(int size)
{
int *result = new int[size];
delete[] result;
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... */
return 0;
}
Definitely not! This is Undefined behavior because you return a deleted pointer. After using the delete operator you're telling your OS that it can release the memory and use it for whatever it wants. Reading or writing to it is very dangerous (Program crashing, Bluescreen, Destruction of the milky way)
int *makeArray(int size)
{
int *result = new int[size];
return result;
}
int main()
{
int *pointer = makeArray(10);
/* code ... do some stuff with pointer */
delete[] pointer;
return 0;
}
Is this safe or does it cause a memory leak?
Yes this is the correct way of using the new and delete operator. You use new so your data stays in memory even if it gets out of scope. Anyway it's not the safest code because for every new there has to be a delete or delete[] you can not mix them.
Is there a better way of returning the pointer?
YES. It's called Smart Pointer. In C++ programmers shouldn't use new but smart pointer at all. There is a C++ community Coding Guideline to avoid these calls Guideline R11
i have a segment fault when it calls the function unit_thread_data,Actually it is caused by ~Data(). thread1 is all right, but thread2 cause the segment fault, the whole code is as fallows:(forgive the poor code style), error info is double free or corruption. Other info: gcc5.4.0, centos7. any help? thank you very much!
#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;
class Data
{
public:
int* A_;
Data()
{
cout<<"111\n";
A_=NULL;
}
~Data()
{
cout<<"222\n";
if(A_) {
delete A_;
}
}
};
struct thread_data_t
{
Data* d;
};
void* _add(void* _pthread_data)
{
thread_data_t* pthread_data = (thread_data_t*) _pthread_data;
pthread_data->d->A_ = new int[2];
pthread_data->d->A_[0] = 1;
pthread_data->d->A_[1] = 2;
std::cout<<pthread_data->d->A_[0]+pthread_data->d->A_[1]<<endl;
return (void*)0;
}
void unit_thread_data(thread_data_t* pthread_data)
{
for(int i=0;i<2;i++)
{
delete[] pthread_data[i].d->A_;
delete pthread_data[i].d;
}
delete[] pthread_data;
}
int main()
{
int num_threads = 2;
pthread_t threads[num_threads];
thread_data_t* pthread_data = new thread_data_t[num_threads];
for(int i=0;i<num_threads; i++)
{
pthread_data[i].d = new Data();
}
for (int i=0; i<num_threads; i++) {
pthread_create(&threads[i], NULL, _add, (void*)(pthread_data+i));
}
for (int i=0; i<num_threads; i++) {
pthread_join(threads[i], NULL);
}
sleep(1);
unit_thread_data(pthread_data);
return 0;
}
delete[] pthread_data[i].d->A_;
This deletes the A_ member of your Data class, an int *.
Immediately afterwards, this happens:
delete pthread_data[i].d;
And this deletes the Data itself. Data's destructor then does the following:
if(A_) {
delete A_;
}
This then proceeds to attempt delete the same pointer. This should be delete[]d instead of deleted in the first place, but this is moot because this pointer is already deleted, and this tries to delete it a 2nd time.
This results in undefined behavior.
It is because you first delete member A_ here:
delete[] pthread_data[i].d->A_;
without assigning nullptr to A_ afterwards, and then you call delete A_; in the destructor.
Apart from that, in your code it is not clear who should be the owner of the memory allocated under A_ (functions _add and unit_thread_data, or a class itself), hence it is easy to do this kind of mistakes.
Quick fix (not recommended): just remove your destructor's body, and let your external functions _add and unit_thread_data manage the memory.
Better fix (recommended): think about who should be the owner of the allocated data (I would say class Data) and use std::unique_ptr if you can.
You need to assign NULL after deleting A_.
In the following code sample Visual Studio gives me the error "A heap has been corrupted". At first the for-loop seems to work fine, but after 1 or 2 iterations it just crashes.
I feel that my function myReAllocate facilitates some sort of memory leak where it shouldn't (because when I comment it out, everything works fine). What exactly is going on? It seems like a very subtle error.
#include <iostream>
using namespace std;
class myClass{};
void myReAllocate(myClass* c)
{
delete c;
c = new myClass();
}
int main(void)
{
myClass *cc[10];
for (int i = 0; i < 10; i++){
cout << i << " attempt" << endl;
cc[i] = new myClass();
myReAllocate(cc[i]);
delete cc[i];
}
return 0;
}
I have tried adding a operator= but it didn't help either.
myClass operator=(myClass& right) {
myClass temp = right;
return *this;
}
myReAllocate gets the address of the myClass as parameter. You then free that address and allocate a new object and assign it to the local variable. This has no effect on the value of cc[i]. So when you then delete cc[i] you delete the already deleted object again.
If you want do to something like that then you need to pass the address of cc[i] (or reference to it) so you can change it:
void myReAllocate(myClass** c)
{
delete *c;
*c = new myClass();
}
I would go for reference instead of pointer as parameter:
void myReAllocate(myClass*& c)
{
delete c;
c = new myClass();
}
as this would not require client code change. Goswin's proposal requires the call to myReAllocate to be:
myReAllocate(&cc[i]);
while references allow it to be called without a change.
In the below code, Why i couldn't able to access test_var from main? My assumptions are that new allocates memory in heap, so the lifetime is till the end of the main, or till you explicitly delete it. But when i try to access test_var, i get exception.
typedef struct test{
int a;
string str;
}test;
void fun1(test* test_var)
{
test_var = new test[2];
test_var[0].a=1;
test_var[0].str='a';
test_var[1].a = 2;
test_var[1].str = 'b';
return;
}
int main()
{
test *test_var = NULL;
fun1(test_var);
cout<<test_var[0].str;
delete test_var;
return 1;
}
Because test_var is local to fun1, and the assignment
test_var = new test[2];
only has effect within the function.
You need
void fun1(test** test_var)
{
*test_var = new test[2];
...
}
and in main:
test *test_var = NULL;
fun1(&test_var);
P. S. This isn't really C++ code. Raw pointers manipulation is dangerous and should be avoided. C++ has much cleaner mechanisms for doing what you're trying to do. See std::vector, std::shared_ptr.
It is because in function fun1, test_var is a local variable.
void fun1(test* test_var)
Hence, any modification done in fun1 is done on local variable.
You need to do:
void fun1(test*& test_var)
I'm trying to assign a node to a pointer along an array of pointers but it keeps telling me that my array was not declared in the scope. I'm totally confused on how or why so any help would be greatly beneficial! Thanks for taking the time to respond!
#include <iostream>
#include "book.h"
using namespace std;
class bookstore
{
private:
int amount = 5;
int counting = 0;
public:
bookstore()
{
bookstore *store;
store = new book*[amount];
for(int i = 0; i < amount; i++)
{
store[i] = NULL;
}
}
~bookstore(){ delete[] store; }
void addbook(string a,string b, string c, string d, string e)
{
if (counting == amount)
{
cout<<"Full House!"<<endl;
return;
}
store[counting] = new book(a,b,c,d,e);
counting++;
}
void print()
{
for(int i = 0; i < amount; i++)
{
cout<<store[i]->name<<" "<<store[i]->publisher<<" "<<store[i]->year<<" "<<store[i]->price<<" "<<store[i]->category<<endl;
}
}
};
Your pointer store is local to the default constructor. It looks like you're after a data member. Furthermore, you seem to be after an array of pointers. If so, you need bookstore needs to be a pointer to pointer:
class bookstore
{
private:
bookstore** store; // or bookstore* store
int amount = 5;
int counting = 0;
and fix the constructor to use that:
bookstore()
{
store = new book*[amount]; // or store = new book[amount]
....
Note that your class is attempting to manage dynamically allocated resources, so you will need to take care of the copy constructor and assignment operators (either make the class non-copyable and non-assignable, or implement them. The defaults are not acceptable. See the rule of three.) If you are really using an array of dynamically allocated pointers, then you need to fix your destructor too. Currently, it only deletes the array, but not the objects pointed at by the pointers in it.
The better solution would be to use a class that manages the resources for you and has the desired semantics. It is easier to have each class handle a single responsibility.