• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 280
  • Last Modified:

About pointers

Hi,

I would like to ask the following questions about pointer in C++.
I have writen a class called Draw and I call it in the following ways.
1. Draw *draw;
   draw->getSize();
2. Draw *draw=new Draw;
   draw->getSize();
What's the difference between the above 2? and are they all needed to be deleted after use? as method one is not created using new, so i guess it dun need to be deleted. Am I right?

Besides, for the following codes,
int number1=10;
int &ref=number1;
Are there two "10" values present in the system, i.e. one is ref and the other is number? or just one "10" value, i.e. both ref is pointing to number1?

Thanks a lot ^^

Sherina
0
sherina
Asked:
sherina
  • 4
  • 3
  • 3
  • +4
1 Solution
 
beavis_shenzhenCommented:
1:
    Draw *draw; draw->getSize();
At compiling time, no error message would be prompted.
but exception will be thrown in the execution of these codes. because the class pointer is not initialized by a construct function.
  for debug version,the pointer will be set to 0xcccc,and for release version,the value of the pointer is 0x0000. all
refer to illegal address.
 2:
   Draw *draw=new Draw;
   draw->getSize();
the pointer is initialized by new(),so things will be ok.
but you need to delete the class when its not in need.
 delete[] draw;
hope these help.
   
0
 
desmondliuCommented:
ref reference to number1. there is only one 10.
0
 
bistricaCommented:
1) Draw *draw;
will create a pointer variable. It's useles unles initialized as it is only a ponter to nothing (NULL).
So draw->getSize(); is useless until you initialize draw pointer to some value. Like: draw = GetDrawBlock();

2) Draw *draw=new Draw; will create a memory block to hold Draw object. draw pointer points to that block. Block is placed in "heap" or "free" memory and it will be marked as reserved until it's freed with delete.
draw is not NULL.
With new draw will be created using draw constructor.

==========================================================

Creates number1 and initialize it to 10, so you have memory block to accomodate an integer with value 10.
& is address, so &ref tells that ref is addres of integer. In your case ref is  address of number1.

Thus, you have just one value 10 in memory named number1 and you have an addres to number1.

int number1=10;
int &ref=number1;
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
sarda_rameshCommented:
Hi there,
 
 The code
  Draw *draw;
  draw->getSize();
 declares a pointer to an object of class Draw. As for any other auto variable , this pointer will contain some garbage value and therefore the results will be unpredictable. In general if the garbage value that the varaible draw contains is outside the range of memory allocated for ur process, u will get a segmentation fault (in Unix). The other one is fine as memory is being allocated for the variable and it has been initialized to point to a particular address where the values for the object are stored.

As for ur second problem, a reference variable is an alias (that is another name) e.g, its like nick name , a person can have many names. Similarly a reference variable is a second name given to a variable already defined. Therefore there will be only one value 10 stored.

regards
ramesh
0
 
SalteCommented:
wowowow,

Draw * draw;

This does not declare an object of type "Draw", it declares a POINTER to an object of type Draw. This pointer is currently not pointing anywhere.

It is therefore an error to call the function through that pointer:

draw -> getSize();

is therefore an error.

The only thing you can legally do with a pointer variable like the above is to initialize it to point to some object or to initialize it to point to no object by setting the pointer to point to 0 (NULL).

draw = 0;

will initialize the pointer to point to no object. It is therefore still not possible to call any function through that pointer:

draw -> getSize();

is still not legal.

Another thing you can do is to set it to point to some object:


Draw someObj;

draw = & someObj;

Now you can do:

draw -> getSize();

and it will have the same effect as if you had done:

someObj.getSize();

Such a pointer should not be deleted since you didn't allocate it by new.

Another way you can initialize the pointer is by setting it to point to an object on the heap that you allocate:

draw = new Draw();

now you can also use draw -> getSize(); and now you must delete the object when you're done with it. However, the deletion is associated with the object and not with the pointer.

Another way you can initialize the pointer is to set it to point to some other pointer that already point to a valid object:

draw = other_draw;

where other_draw is a Draw * pointer that is initialized by one of the other methods that gets you a valid object (either & obj or using new).

It is important to understand that if other_draw was invalid (either not initialized or initialized to 0) then draw will also be invalid and you still cannot call draw -> getSize(); but if other_draw was valid then you can now call draw -> getSize() and it has the same effect as if you did other_draw -> getSize().

As I said, the deletion follow the object and not the pointer, so if you do something like this:

Draw * draw = new Draw;

Draw * other_draw = draw;

then you can do:

draw = 0;

you should not do 'delete draw' at this point unless you also want other_draw to not have the object any more. If you want other_draw to point to the object you should NOT delete it since other_draw still wants to point to it.

It is also important that if you have two pointers pointing to the same object and you delete the object by doing:

delete one_pointer;

you should also remember that the other pointer also point to an invalid location at this point and it is just as if you didn't initialize that pointer at all.

Also, delete one_pointer do not modify one_pointer so after this call one_pointer is also pointing to an invalid location and you should therefore set one_pointer to 0 unless the pointer is about to vanish itself.

so:

delete one_pointer;
one_pointer = 0;

is safe, if you other pointers pointing to the same object those should be set to 0 also.

Of course, in a destructor you don't have to do that since the member is about to go away itself anyway:

class X {
private:
   Y * yobj;

public:
   ~X() { delete yobj; }
};

You don't have to set yobj to 0 in the destructor since the member yobj is part of the X object and will disappear when the destructor is done.

Hope this makes things clearer.

Alf
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Beavis,

>> 2:
>>  Draw *draw=new Draw;
>>  draw->getSize();
>> delete[] draw;

delete draw ;

Bold-braces should not be specified when the memory has been allocated for only one object. If we had:

Draw * draw = new Draw[10] ;

Then,

delete [] draw ;

was all-right.

Mayank.

0
 
sherinaAuthor Commented:
Hi all,

All your answers are very helpful. I feel clearer now.
Thanks a lot ^^

Sherina
0
 
SalteCommented:
You're welcome :-)

Alf
0
 
beavis_shenzhenCommented:
mayank:
    Thanks,you are right.
    but if bold braces is specified, error would occur?
0
 
Mayank SAssociate Director - Product EngineeringCommented:
>> but if bold braces is specified, error would occur?

Not during compilation, I guess. Because at that time, the compiler might not know whether a single object has been allocated or an entire array. It might give an error during run-time....

I guess both these factors (whether there is an error at compile-time or at run-time) will vary across different compilers and versions.

Mayank.
0
 
SalteCommented:
I doubt the error can occur at compile time. It might not occur at run time either, it depends on how good the run time is at detecting the error.

What IS certain is that SOME systems detect it at run time and give run time error.

so:

T * ptr = new T;

delete [] ptr;

Might give run time error on some systems, on some systems it won't give error but weird things will happen and on some systems it won't give an error at all and it will even be handled correctly. It all depends on the implementation.

What is also certain is that it does not form a well defined C++ program. I.e. it is not written the way it is supposed to be written. Thus it might crash the program and in some systems it will.

Similarly for:

T * ptr = new T[100];

delete ptr;

same situation - but reversed - as the situation above.

Alf
0
 
Mayank SAssociate Director - Product EngineeringCommented:
Just tried:

int * p = new int ;
* p = 5 ;
cout << * p ;
delete [] p ;

on Turbo C++.... it didn't compile! It said: "Operand expected in function main ()."

Its safest not to do such things. Some compilers might not report the error during compilation, and like Alf said, it might crash.

Mayank.
0
 
beavis_shenzhenCommented:
tried also:
    code is the same with Mayankeagle's.
    on Visual C++7.0
    No warning at comiling time and no exception at run time.
0
 
Mayank SAssociate Director - Product EngineeringCommented:
So you know now that it will vary across different compilers/ platforms. But don't try it - some might prevent something from going wrong,.... some might not and there might be an adverse effect.

Mayank.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 4
  • 3
  • 3
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now