Pointers or not pointers?

Dear all, I have a curiosity that I never understood correctly.

Inside a function, if I need a double to compute something, what should I use double or double* ? If I use double* can I delete it inside the function?

Thanks.
It all depends.

If you want a function to pass values back, you either have the function return or pass the variables in by reference.

Pass by Reference
Passing parameters by reference means passing the address of the variable. Most languages wrap this up nicely so you never have to deal with addresses. But C, being what it is, doesn't have a reference mechanism and requires the programmer to pass the address of things whenever references are requiired.

This example passes a double by reference using pointers as you would do in C.
1
2
3
4
5
6
7
8
9
10
11
void init(double *pValue)
{
    *pValue = 0.0;
}

int main()
{
    double d;
    init(&d);    // pass d by reference by passing its address
    return 0;
}


C++ does provide reference variables, so the use of a pointer is sort of hidden. Here's the equivalent example using pointers.
1
2
3
4
5
6
7
8
9
10
11
void init(double &Value)
{
    Value = 0.0;
}

int main()
{
    double d;
    init(d);    // pass d by reference
    return 0;
}


New and Delete
In C, there's an area of free memory called the heap. If you need some memory, you can ask for some and if there's enough available, you'll be told where the memory block starts. When you're done, you need to give it back, so the heap can reuse that memory on a later request.

In C++, you ask for memory by calling new. And you give it back by calling delete.

It's an error to delete memory that was not obtained by using new.

Here's an example of how it may be used.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

int main()
{
    size_t array_size = 0;
    std::cout << "Please enter a size: ";
    std::cin >> array_size;

    int* array = new[array_size];    // ask for some memory
    if (array != 0)    // check if the request for memory succeeded
    {
        int sum = 0;
        for (size_t i = 0; i != array_size; ++i)
        {
            std::cout << "value " << i << " : ";
            std::cin >> array[i];
            sum += array[i];
        }
        std::cout << "average is: " << sum/array_size << std::endl;
        delete [] array;    // give the memory back
    }
    else
        std::clog << "out of memory" << std::endl;
    return 0;
}
Last edited on
Thanks for your reply.
But what is the difference in term of memory allocation & usability of this:

1
2
3
4
5
6
7
8
9
10
11
void DoSomething() //this is a function not a main
{
      double a = 5;
      cout<<a<<endl;
//or 
      double *a = new double;
      a = 5;
      cout<<a<<endl;
      delete a;

}
Shoud be:
1
2
3
4
5
6
7
8
9
10
void DoSomething() //this is a function not a main
{
      double a = 5;
      cout<<a<<endl;
//or 
      double *a = new double;
      *a = 5;
      cout<<*a<<endl;
      delete a;
}


The C memory model has a heap and a stack. Each time your function is called, a new activation record is placed on the stack. This has all the local variables and parameters passed to the function.
1
2
3
4
5
void DoSomething() //this is a function not a main
{
      double a = 5;
      cout<<a<<endl;
}

This declares what we call a local variable. It lives on the stack. Each time DoSomething() is called a new a is created on the stack. a is destroyed when the stack is popped when the function returns.

1
2
3
4
5
6
7
void DoSomething() //this is a function not a main
{
      double *a = new double;
      *a = 5;
      cout<<*a<<endl;
      delete a;
}

In this example, each time DoSomething() is called, a new a is created on the stack. This a is a pointer to double. The code allocates some memory from the heap. No check is made for success. a is 'dereferenced' to get the value from the heap and it's assigned value 5.0. a is 'dereferenced' again to get the value, which is printed. a is handed back to the heap. a is destroyed when the stack is popped when the function returns.
Last edited on
Even better: if you use usual variables instead of manual memory management using new and delete, the compiler can optimize to never have your variable in the memory but only in the processor registers.
Great! Thank you very much for the good explanations!
closed account (1yR4jE8b)
kbw wrote:
1
2
3
 int* array = new[array_size];    // ask for some memory
    if (array != 0)    // check if the request for memory succeeded
    {


This code is not correct:

First of all: when you ask for memory your call to new doesn't have a type-specifier. This shouldn't even compile.

Second: Unless you pass std::nothrow in a call to new, if it fails it will not return a NULL pointer, it throws an std::bad_alloc exception. This code will never reach the 'else' section.
Topic archived. No new replies allowed.