Dynamic memory (new) question.

I'm just curious, in the tutorial it allows for:

pointer = new type;

and

pointer = new type[];

If the point of dynamic memory is that it's length is variable what is the point of the first expression (which has a length of one byte)?
First line creates a singve variable of type Type and stores it address in pointer.
Second creates several (you should specify how many) variables successively placed in memory and store address of first in pointer. You can use it as array here.
If the point of dynamic memory is that it's length is variable what is the point of the first expression (which has a length of one byte)?

The point of dynamic memory is that it is dynamic. When you need an object to live beyond the current scope, it needs to be allocated dynamically.
@cire
Please explain what is meant by:
When you need an object to live beyond the current scope


thanks
Consider a dialog box in a Windows program. You want to create it when you want it displayed. You delete it when you're done with it. Depending on the structure of your program, the creation and deletion of the dialog box might not be done in the same function (scope).
The first two responders thanks for replying but I don't think you understand the question. I wasn't asking what the point of dynamic memory is, I was asking what the point of dynamic memory that has a maximum size of one byte is.

abstractionanon, that sounds like it could be a good answer to my question, but I've not gotten far enough in my learning to know for sure. I will take it for now as "keep learning and you'll find out". Thanks.
If the point of dynamic memory is that it's length is variable what is the point of the first expression (which has a length of one byte)?


at least it can be deleted, if it's not being used anymore. and, thus, it will make the pointer point to an empty address, and have NULL value

1
2
3
4
5
int * point = new int;
//...
std::cout << "*point is: " << *point << std::endl;
delete point;
std::cout << "point is: " << point << std::endl; //point will have NULL address 


btw, i haven't compile the code yet (but, i'm sure the result are the same as i said)

CMIIW
Delete is covered in the next section. I suppose I should've kept my mouth shut and kept reading, lol. Sorry, and thanks.
Deleting a pointer will not make it null. It will still point to the same memory, that memory will just not be allocated any longer.

You don't actually delete the pointer, you delete what the pointer points to.
Last edited on
Please explain what is meant by:
When you need an object to live beyond the current scope


Well, let's say you wanted to create a c-style string holding the binary representation of a number:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <limits>
#include <cstdlib>

void printBinaryString(unsigned) ;

int main()
{
    unsigned num ;

    std::cout << "Enter non-numeric input to quit.\n" ;

    while ( (std::cout << "Enter a number: ") && (std::cin >> num) )
        printBinaryString(num) ;
}

void printBinaryString(unsigned num)
{
    const int binaryRadix = 2 ; 
    char str[std::numeric_limits<unsigned>::digits+1] = {0} ;

    itoa(num,str,binaryRadix) ;
    std::cout << str << '\n' ;
}


Everything is all well and good here, but suppose we want to divorce the printing of the string from generation of the string representation? That means that the program needs a little restructuring. We can probably begin with a new name and prototype for generating the string:

char* toBinaryString(unsigned num)

and if we go for a straightforward conversion of the code we might come up with:

1
2
3
4
5
6
7
8
char* toBinaryString(unsigned num)
{
    const int binaryRadix = 2 ; 
    char str[std::numeric_limits<unsigned>::digits+1] = {0} ;

    itoa(num,str,binaryRadix) ;
    return str ;
}


but we come up against a problem here. str only exists inside of toBinaryString. When toBinaryString returns, the memory occupied by str is reclaimed. One way to get around this is to use dynamic memory, giving us a program that looks like the following:

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
26
27
28
#include <iostream>
#include <limits>
#include <cstdlib>

char* toBinaryString(unsigned) ;

int main()
{
    unsigned num ;

    std::cout << "Enter non-numeric input to quit.\n" ;

    while ( (std::cout << "Enter a number: ") && (std::cin >> num) )
    {
        char* s = toBinaryString(num) ;
        std::cout << s << '\n' ;
        delete [] s ;
    }
}

char* toBinaryString(unsigned num)
{
    const int binaryRadix = 2 ; 
    char* str = new char[std::numeric_limits<unsigned>::digits+1] ;

    itoa(num,str,binaryRadix) ;
    return str ;
}


Now, you can probably tell this example is a bit contrived (we may have wanted to store those strings to manipulate them later, for instance.) There are better ways to do this in both C and C++. In C++ using std::string (which manages dynamic memory internally so you don't have to) would be appropriate, but hopefully it illustrates the lifetime issue for you.

Last edited on
I was asking what the point of dynamic memory that has a maximum size of one byte is.

In the example you quoted:
 
  pointer = new type; 

it's not clear what type type is. It can be a builtin type such as char or int, or it can be a class. It's not necessary to know how big type is. The compiler takes care of that.

I was asking what the point of dynamic memory that has a maximum size of one byte is.

It doesn't have the size of one byte. It has the size enough to fit one instance of whichever type you specify:
1
2
3
4
5
6
7
struct Foo
{
    int bar;//4 bytes on my compiler
    double baz;//8 bytes
};
//...
Foo* x = new Foo;//allocates sizeof(Foo) or 12 bytes 

You need dynamic memory allocation of one object if you want to return a pointer to local value from function:
1
2
3
4
5
6
7
8
9
10
11
Foo* func()
{
    Foo x;
    return &x;//Will not work: x has function scope 
}

Foo* y()
{
    Foo* x = new Foo;
    return x;//works
}

Or just need to allocate object in heap:
1
2
3
4
5
6
7
8
struct Foo
{
    double bar[10000][10000];
};

//...
Foo x;//Probably stack overflow here
Foo* y = new Foo;//If you have enough memory, you'll be fine 
Last edited on
ok thanks cire and MiniPaa. So if I have understood correctly from your respective examples, when we write a function lik√ę:

1
2
3
4
int* func() {
  int* x = new (int);
  return x;
}


x is a local pointer variable so it vanishes after the return statement but the memory to which it points to is very much present and any pointer (probably the pointer to which the value of function is assigned to) can have its address.
Yes, you are correct.
@cire: what is happening in here?
1
2
3
4
5
6
7
8
char* toBinaryString(unsigned num)
{
    const int binaryRadix = 2 ; 
    char* str = new char[std::numeric_limits<unsigned>::digits+1] ;

    itoa(num,str,binaryRadix) ;
    return str ;
}


i thought it was just the same as:
1
2
3
4
5
6
7
8
char* toBinaryString(unsigned num)
{
    const int binaryRadix = 2 ; 
    char str[std::numeric_limits<unsigned>::digits+1] = {0} ;

    itoa(num,str,binaryRadix) ;
    return str ;
}


because (i think) they both create temporary variables (and memories?) on the function, and after the function ends, they're destroyed.
No. In first case we explicitely allocating our str array in heap. At the end of function we will pass copy of str pointer to calling function and original pointer will be destroyed, but not the memory it points to.

In second case we are allocating our str array in stack. At the end of function copy of pointer to the beginning of str array will be returned, but memory which contains said array will be deallocated and any attempt to use returned pointer will lead to undefined behavior.
chipp, in the first function, str is a pointer that points to memory allocated by new, and the value of str (the address of the new'd memory) is returned to the calling function.

In the second function, str is an array that is allocated on the stack. The address of the array is returned to the calling function, but the array ceases to exist when the function returns.
Topic archived. No new replies allowed.