#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define ROW 1
class Foo
{
public:
Foo()
{
this->dummy = new unsigned int[100];
}
~Foo()
{
delete[] this->dummy;
this->dummy = NULL;
}
unsigned int* dummy;
};
Foo** allocate()
{
Foo** foo_array = NULL;
foo_array = new Foo * [ROW]; //Create space for Foo addresses (row)
for (int i = 0; i < ROW; i++)
foo_array[i] = new Foo; //Create and allocate Foo for each address space(col)
return foo_array;
}
int deallocate(Foo* foo_array[ROW])
{
if (foo_array != NULL)
{
for (int i = 0; i < ROW; i++)
delete foo_array[i];
delete[] foo_array;
foo_array = NULL;
return 1;
}
return 0;
}
void main()
{
Foo** foo_array = NULL;
foo_array = allocate();
deallocate(foo_array);
if (foo_array != NULL)
printf("not null something wrong\n");
system("pause");
}
In main() function, foo_array should be pointed to NULL as soon as the deallocation is performed by the deallocate(Foo* foo_array[ROW]) function.
but, In deallocate(Foo* foo_array[ROW]) function,
foo_array = NULL;
It seems point to NULL by above syntax, however in main() function,
foo_array is not point to NULL.
so, I tried to change above syntax in deallocate(Foo* foo_array[ROW]) function,
foo_array = NULL; => (*foo_array) = NULL;
It spits out write access violation errors.
Where did it go wrong?
I don't see any reason to declare foo_array as pointer to pointer. In your code you are passing pointers by value. That means you can change what the pointers are pointing at but you can't change the values of the pointers. You can solve the problem using references.
#include <cstdio>
#define ROW 1
class Foo
{
public:
Foo()
{
this->dummy = new unsigned int[100];
}
~Foo()
{
delete[] this->dummy;
this->dummy = NULL;
}
unsigned int *dummy;
};
void allocate(Foo *&foo_array)
{
foo_array = new Foo[ROW];
}
void deallocate(Foo *&foo_array)
{
delete[] foo_array;
foo_array = nullptr;
}
int main()
{
Foo *foo_array = nullptr;
allocate(foo_array);
deallocate(foo_array);
if (foo_array != nullptr)
printf("not null something wrong\n");
}
Of course you can make your code much simpler using STL containers or smart pointers
The correct syntax would be foo_array = deallocate (foo_array); and your deallocate should return NULL.
Related
I'm using C++ and am trying to set an array element values with a setter method. The array is a class private member:
class Boo{
private:
int *x;
public:
Boo();
~Boo();
void setX(int,int);
int getX(int);
}
Boo::Boo(){
x = new int[1];
x = 0;
}
void Boo::setX(int value, int index){
//set condition for NULL
x[index] = value;
}
int Boo::getX(int index){
if(x[index] == NULL) {cout<<"invalid index"<<end; return;}
return x[index];
}
void test(){
Boo *p = new Boo();
p->setX(12,0);
cout<<p->getX(0)<<endl;
}
I been trying to test setting the values in 'x' starting with index '0' (like test()) but it crashes. I wanted to write a program where I run a loop counting up, and I set the array values. Can this be accomplish this way?
Do not use new in C++!
In this case, you should use std::vector<int>.
If you want to fix your code unless use std::vector,
#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <memory>
using std::size_t;
class Boo {
private:
int *x;
size_t size;
size_t capacity;
public:
Boo();
~Boo();
void setX(int,size_t);
int getX(size_t);
};
Boo::Boo() : size(), capacity(1) {
this->x = new int[1];
//x = 0;//DO NOT ASSIGN NULL POINTER!!!!
}
Boo::~Boo() noexcept {
delete[] x;
}
void Boo::setX(int value, size_t index){
if(this->capacity <= index) throw std::out_of_range("Boo::setX");//YOU MUST CHECK RANGE
this->x[index] = value;
++this->size;
}
int Boo::getX(size_t index){
if(this->size <= index) throw std::out_of_range("Boo::getX");//YOU MUST CHECK RANGE
return x[index];
}
void test(){
auto p = std::make_unique<Boo>();
p->setX(12,0);
std::cout << p->getX(0) << std::endl;
}
int main(){
test();
}
http://melpon.org/wandbox/permlink/aIhwC5c9o1q8ygIo
Boo::Boo()
{
x = new int[1];
x = 0;
}
you are not able to set value in an array because after initializing with memory, you have set the pointer of an array to null in constructor.
please use x[0] = 0; instead of x = 0;
As the following code.
I want to move the element in vector to back.
eg:
[(1),2,3,4] -> [2,3,4,(1)]
But, it cause double free problem.
The logic in this code is simple.
I think I misuse the erase function.
Is it true? Would anyone tell me the detail?
Thanks for your reading.
This is output:
*** Error in '/home/ubuntu/workspace/hello-cpp-world.cc.o': double free or corruption (out): 0x00000000016ffca0 ***
This is the code snippet:
#include <iostream>
#include <vector>
int main() {
std::vector<int*> targets;
int* a = new int;
*a = 1;
int* b = new int;
*b = 2;
targets.push_back(a);
targets.push_back(b);
int i =0;
for (std::vector<int*>::iterator obj1 = targets.begin(); obj1 != targets.end(); i++)
{
if(i==0)
{
int* tmp = *obj1;
targets.push_back(tmp);
targets.erase(obj1);
}
else obj1++;
}
}
Invoking push_back or erase to std::vector may invalidate iterators. It is easier to use indexes.
#include <iostream>
#include <vector>
int main() {
std::vector<int*> targets;
int* a = new int;
*a = 1;
int* b = new int;
*b = 2;
targets.push_back(a);
targets.push_back(b);
int i =0;
for(size_t obj1 = 0; obj1 < targets.size(); i++)
{
if(i==0)
{
int* tmp = targets[obj1];
targets.push_back(tmp);
targets.erase(targets.begin() + obj1);
}
else obj1++;
}
}
Since obj1 isn't used other than incrementing except for when i==0, you can write more simply
#include <iostream>
#include <vector>
int main() {
std::vector<int*> targets;
int* a = new int;
*a = 1;
int* b = new int;
*b = 2;
targets.push_back(a);
targets.push_back(b);
int* tmp = targets[0];
targets.push_back(tmp);
targets.erase(targets.begin());
}
Is there a way to know whether the memory of a pointer variable has been allocated using new or malloc?
int* a = new int;
int* b = static_cast<int*>(malloc(sizeof *b));
//Maybe using a function?
allocatedwithnew(a); //Returns true
allocatedwithmalloc(b); //Return true
Why don't you try with counters?
As far as I understand your code looks like this:
if(ConditionA) {
A obj = new A;
} else {
A obj = malloc(sizeof(int));
}
You could do something like this:
#include <iostream>
#include <stdlib.h>
using namespace std;
struct A{
int ab;
bool createdByNew;
};
int main()
{
int CountNewAllocations=0;
int CountMallocAllocations=0;
bool Condition=true; // this will be set to appropriate value
A *obj = NULL;
if(Condition) {
obj = new A;
obj->createdByNew=true;
CountNewAllocations++;
} else {
obj = (A*) malloc(sizeof(A));
obj->createdByNew=false;
CountMallocAllocations++;
}
// ... use the object
if(obj!=NULL) {
if(obj->createdByNew) {
delete obj;
CountNewAllocations--;
} else {
free(obj);
CountMallocAllocations--;
}
}
return 0;
}
You could use a define which replaces new with NEW, and then set the define to
static int newCounter = 0;
#define NEW(A) ++newCounter; new A
static int mallocCounter = 0;
#define MALLOC(A) ++malloCounter; malloc A
I have seen a class like this on the internet,
the head file
#ifndef _COMMON_ARRAY_OBJECT_POOL_H_
#define _COMMON_ARRAY_OBJECT_POOL_H_
#include <stdint.h>
namespace easynet
{
class ArrayObjectPool
{
public:
/** construct
* #param elem_size : element size;
* #param elem_num : element number
*/
ArrayObjectPool(uint32_t elem_size, uint32_t elem_num);
~ArrayObjectPool();
uint32_t ElemSize(){return m_ElemSize;}
uint32_t Capacity(){return m_ElemNum;}
bool IsEmpty(){return m_FreeHead==NULL;}
void* Get();
bool Recycle(void *elem);
private:
void *m_Elements;
void *m_End;
void *m_FreeHead;
uint32_t m_ElemSize;
uint32_t m_ElemNum;
};
}
#endif //_COMMON_ARRAY_OBJECT_POOL_H_
the cpp file
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include "ArrayObjectPool.h"
namespace easynet
{
ArrayObjectPool::ArrayObjectPool(uint32_t elem_size, uint32_t elem_num)
{
m_ElemNum = elem_num;
if(elem_size < sizeof(void*))
m_ElemSize = sizeof(void*);
else
m_ElemSize = elem_size;
m_Elements = malloc(m_ElemSize*m_ElemNum);
m_End = (void*)((char*)m_Elements+m_ElemSize*m_ElemNum);
assert(m_Elements != NULL);
//construct list
int i;
void *node = m_Elements;
for(i=0; i<m_ElemNum-1; ++i)
{
*(void**)node = (void*)((char*)node+m_ElemSize);
node = *(void**)node;
}
*(void**)node = NULL;
m_FreeHead = m_Elements; //list head
}
ArrayObjectPool::~ArrayObjectPool()
{
free(m_Elements);
}
void* ArrayObjectPool::Get()
{
if(m_FreeHead == NULL)
return NULL;
void *temp = m_FreeHead;
m_FreeHead = *(void**)m_FreeHead;
return temp;
}
bool ArrayObjectPool::Recycle(void *elem)
{
if(elem<m_Elements || elem>=m_End)
return false;
*(void**)elem = m_FreeHead;
m_FreeHead = elem;
return true;
}
}
The question is I can't understand what does this means:
int i;
void *node = m_Elements;
for(i=0; i<m_ElemNum-1; ++i)
{
*(void**)node = (void*)((char*)node+m_ElemSize);
node = *(void**)node;
}
and what the *(void**) means? thanks!
It's treating the memory as if it were a union between the user's data type, and void*. When the blocks are in the free block list, the void* is used.
You can think of it as:
union ObjectInObjectPool
{
void* ptr_next_free_block;
UserType content;
};
and then that loop is basically doing:
ObjectInObjectPool* node = m_Elements;
for(i=0; i<m_ElemNum-1; ++i) {
node->ptr_next_free_block = node + 1;
node = node->ptr_next_free_block;
}
except that the programmer did by hand all the pointer arithmetic that the compiler's type checker usually does.
A void* is a pointer value that points to untyped memory. When you do *(void**)node = ..., what it is really doing is *node = .... However, with the latter, you are trying to assign something to a void which doesn't make sense with C++'s type system; you have to do as in the former and cast it to a void** so that *node will be a void*, not a void, and you can assign to it.
node = *(void**)node is just node = *node but forcing the type system to work. It just does "assign to node the value of the memory at *node interpreted as a void*".
#include"iostream"
class CMessage
{
public:int a;
CMessage(){}
~CMessage(){}
};
void Testing(CMessage *f_pMessage)//l_pMessage is output parameter
{
f_pMessage = new CMessage();
f_pMessage->a = 1;
}
int main()
{
CMessage *l_pMessage =NULL;
Testing(l_pMessage);
std::cout<<l_pMessage->a;//getting l_pMessage = NULL;
return 0;
}
When I called testing then inside testing f_pMessage is getting initialized but as soon as
i after excuting testing function it should be store in l_Pmessage but it is showing NULL.confussed.....
Testing(l_pMessage);
At this line, you are passing a copy of the pointer. You either need to pass a pointer to pointer or a reference to pointer:
void Testing(CMessage *& f_pMessage)//l_pMessage is output parameter
{
f_pMessage = new CMessage();
f_pMessage->a = 1;
}
You can do it the other way using a pointer to pointer:
void Testing(CMessage **f_pMessage)//l_pMessage is output parameter
{
*f_pMessage = new CMessage();
(*f_pMessage)->a = 1;
}
But you have to call the function this way:
Testing(&l_pMessage);
Passing by pointer only allows you to modify what is being pointed at. The pointer itself is still being passed by value.
Since you want to change a pointer, you can either pass a pointer to a pointer or take the pointer by reference:
void Testing(CMessage *&f_pMessage)//l_pMessage is output parameter
{
f_pMessage = new CMessage();
f_pMessage->a = 1;
}
The pointer itself is copied by value.
f_pMessage = new CMessage();
modifies the pointer itself, not the object it points to. Try:
void Testing(CMessage *f_pMessage)
{
f_pMessage->a = 1;
}
int main()
{
CMessage *l_pMessage = new CMessage();
Testing(l_pMessage);
std::cout<<l_pMessage->a;
return 0;
}
Or, if you want to create the object in your function:
CMessage *Testing()
{
CMessage *f_pMessage = new CMessage();
f_pMessage->a = 1;
return f_pMessage;
}
int main()
{
CMessage *l_pMessage = Testing();
std::cout<<l_pMessage->a;
return 0;
}
A pointer to a pointer is the way to go or a pointer reference
void testA(int** var)
{
*var = new int;
**var = 3;
}
void testB(int*& var)
{
var = new int;
*var = 3;
}
Use like this:
// Method a
int* a;
testA(&a);
std::cout << "a: " << *a << "\n";
// Method b
int* b;
testB(b);
std::cout << "b: " << *b << "\n";
// Dont forget to delete!
delete a;
delete b;
I hope this explains it.
The answers I have seen are correct, but they have omitted the most important point I think: you should not use a raw pointer, because you don't have any ownership semantics here.
void Testing(std::unique_ptr<CMessage>& message)
{
message = std::unique_ptr<CMessage>(new CMessage());
message->a = 1;
}
int main(int argc, char* argv[])
{
std::unique_ptr<CMessage> l_pMessage;
Testing(l_pMessage);
std::cout << l_pMessage->a;
return 0;
}
This is better because it uses proper semantics to indicate within the code who is responsible for the allocated object, and use the type system to have the compiler enforce correct use.
Now, I would advise another interface:
std::unique_ptr<CMessage> Testing()
{
return std::unique_ptr<CMessage>(new CMessage(1));
}
int main(int argc, char* argv[])
{
std::unique_ptr<CMessage> l_pMessage = Testing();
std::cout << l_pMessage->a;
return 0;
}