20

I assume that char* = "string" is the same to char* = new char[6]. I believe these strings are created on the heap instead of the stack. So do I need to destroy them or free their memory when I'm done using them or do they get destroyed by themselves?

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
Malik Daud Ahmad Khokhar
  • 13,470
  • 24
  • 79
  • 81

8 Answers8

35

No. You only need to manually free strings when you manually allocate the memory yourself using the malloc function (in C) or the new operator (in C++). If you do not use malloc or new, then the char* or string will be created on the stack or as a compile-time constant.

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
Mike McQuaid
  • 9,615
  • 6
  • 33
  • 38
18

No. When you say:

const char* c = "Hello World!";

You are assigning c to a "pre-existing" string constant which is NOT the same as:

char* c = new char[6];

Only in the latter case are you allocating memory on the heap. So you'd call delete when you're done.

5

The name of the game is "destroy only what you created". Here are the pairs:

  1. malloc/free
  2. calloc/free
  3. new/delete
  4. new []/delete []

Since you created the 2nd string using new [], the onus is on you to destroy it with delete []. Call delete [] string2 when you are done.

Now if your code is convoluted enough and makes keeping track of deletions difficult, consider the usage of scoped pointers or auto pointers. The boost::scoped_ptr class from boost library is a good place to begin. Also look into the RAII idiom, pretty handy and useful stuff.

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
Fanatic23
  • 3,378
  • 2
  • 28
  • 51
4

I assume when I do char* = "string" its the same thing as char* = new char[6].

No. What the first one does is create a constant. Modifying it is undefined behaviour. But to answer your question; no, you don't have to destroy them. And just a note, always use std::string whenever possible.

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
Bernard
  • 45,296
  • 18
  • 54
  • 69
3

They're not the same. Your first example is a constant string, so it's definitely not allocated from the heap. Your second example is a runtime memory allocation of 6 characters, and that comes from the heap. You don't want to delete your first example, but you need to delete [] your second example.

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
Andrew
  • 11,894
  • 12
  • 69
  • 85
1

Let's see what GCC 4.8 x86-64 Linux does

Program:

#include <cstdio>
int main() {
    const char *s = "abc";
    char *sn = new char[4];
    sn[3] = '\0';
    std::printf("%s\n", s);
    std::printf("%s\n", sn);
}

Compile and decompile:

g++ -c -ggdb -o a.o -std=c++98 a.cpp
objdump -CSr a.o

The output contains:

  const char *s = "abc";
 8:   48 c7 45 f0 00 00 00    movq   $0x0,-0x10(%rbp)
 f:   00 
                     c: R_X86_64_32S .rodata
  char *sn = new char[4];
10:   bf 04 00 00 00          mov    $0x4,%edi
15:   e8 00 00 00 00          callq  1a <main+0x1a>
                        16: R_X86_64_PC32       operator new[](unsigned long)-0x4
1a:   48 89 45 f8             mov    %rax,-0x8(%rbp)

Interpretation:

  • char *s = "abc" goes into .rodata. So you cannot free it in any way.
  • char *sn = new char[4]; comes from the output of operator new[]. So you should free it when you can.
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
1

You don't know where the string literals are stored. It may even be read-only memory, so your code should read:

const char* c = "string";

And a new char array should be deleted just like any other dynamically allocated memory area.

aib
  • 45,516
  • 10
  • 73
  • 79
0

new is always an allocation whereas defining a string inline actually embeds the data in the program itself and cannot be changed (some compilers allow this by a smart trick, don't bother).

Some compilers type inline strings so that you cannot modify the buffer.

char* const sz1 = "string"; // embedded string, immutable buffer
char* sz2 = new char[10]; // allocated string, should be deleted
Vincent Robert
  • 35,564
  • 14
  • 82
  • 119