-2

i created char arr[] and assign to it string literal

char arr[] = "some string";                  // arr occupies 12 chars in memory
std::cout << std::strlen(arr)  << std::endl; // lenght is 11 chars + 1 null-terminator
                                             //arr[11] is '\0'

next i put null-terminator into 6 element

arr[5] = '\0';
std::cout << std::strlen(arr) << std::endl; // lenght is 5 chars  + 1 null-terminator
  1. Is it memory leak?
  2. How compiler will know that it must free memory after first '\0'? (when will delete variable arr)
  3. Is it possible to change lenght of this arr variable and notify compiler how much it should free when delete variable?
vova
  • 63
  • 8
  • 5
    There is no memory being allocated here, therefore there cannot be a leak. – Mansoor Aug 18 '20 at 13:03
  • @Mansoor Yes there is. 12 bytes for `arr`. – user253751 Aug 18 '20 at 13:05
  • ***Is it possible to change lenght of this arr variable and notify compiler how much it should free when delete variable?*** An array in c++ is a fixed size at compile time. – drescherjm Aug 18 '20 at 13:05
  • How memory is tracked and freed is all under the hood stuff. It isn't defined how an implementation must free the memory, only that it must (in cases where it must). If `char arr[];` has automatic storage (for example, is a local variable) then it will probably just be "freed" when the stack pointer changes and reused next time the stack grows past where the array used to be. – François Andrieux Aug 18 '20 at 13:06
  • 3
    Does this answer your question? [c++ string allocation](https://stackoverflow.com/questions/3873241/c-string-allocation) – Jan Schultke Aug 18 '20 at 13:06
  • @J.Schultke No. there is different types to which autor assign his string literal. – vova Aug 18 '20 at 14:14

5 Answers5

6

In this code:

char arr[] = "some string";

the variable arr is a static array with a fixed size. There is no dynamic memory allocation here, and so there is no need to be concerned about memory leaks. The compiler will take care of the memory, regardless of what you write into arr.

cigien
  • 57,834
  • 11
  • 73
  • 112
5
  1. Is it memory leak?

No.

  1. How compiler will know that it must free memory after first '\0'? (when will delete variable arr)

The variable is 12 chars. It's the same as writing:

char arr[12] = "some string";

So it will always free 12 chars. The variable is an array of 12 chars; the fact that the 6th char happens to be '\0' is completely irrelevant.

By the way, once you've set the 6th char to '\0', you're still allowed to use all 12 chars, because it's still a 12-char array. Even the ones after the '\0'. But you can't store 13 chars in it.

  1. Is it possible to change lenght of this arr variable and notify compiler how much it should free when delete variable?

No. It is not possible to change the size of any variable.

user253751
  • 57,427
  • 7
  • 48
  • 90
2

For completeness.

There also is no memory leak in allocated memory too, as in:

char* arr = (char*) malloc(12);
strcpy(arr, "some string");
arr[6] = '\0';
free(arr);

Memory management goes by allocated memory (12), not by the underlying usage (nul-terminated char*). (C style, C++ likewise)

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
  • free(arr); <- will delete 12 bytes independantly where is null-terminator? – vova Aug 18 '20 at 14:07
  • @vova Yes. `free` doesn't care about the contents of the allocated memory. – eerorika Aug 18 '20 at 14:13
  • You can cast the malloc void* pointer to anything. C++ `new char[12]` is an other but actually similar matter, needing the invocation of `delete[]`. – Joop Eggen Aug 18 '20 at 14:18
1

Looks like you got it backward. Array size in C++ cannot be changed, period. Because of that fact and because the fact that if you pass array as a pointer you loose information of actual size of that array agreement was created for C style strings - 0 byte aka \0 aka null terminator treated as dynamic end of the string. Agreement means that functions working with C style strings treat that as string termination. That allows you to use fixed size array for strings of different length and to pass only one pointer without size of actual memory to functions to read from it (for example print to screen). Notice, when you pass char array to functions that write data into it you often need to tell it what is actual array size, so that function would not access memory out of bounds as those function would ignore null terminator if it is already there.

That's it, this agreement happens on different layer that arrays managed. So whatever data you put in that array would not affect its size from language point of view, for C++ compiler you created fixed size array you put some data into it and when it's lifetime came to the end compiler destroys it as whole fixed size array. It does not care if you put zero byte there or you did not.

Slava
  • 43,454
  • 1
  • 47
  • 90
0

A memory leak occurs when a memory was allocated by the programmer using the operator new and was not deleted using the operator delete or delete [].

In this declaration

char arr[] = "some string"; 

It is the compiler (or the system) allocated memory for the character array arr that has either the automatic storage duration or the static storage duration. So the compiler (or the system) are responsible to free the allocated memory. The address of the allocated memory is known to the compiler (or the system).

Using this statement

arr[5] = '\0';

you did not reallocate the array. You just changed its content more precisely only one its byte.

How compiler will know that it must free memory after first '\0'? (when will delete variable arr)

Because the compiler (or system) knows how the object of the array type was declared.

For the object there was allocated 12 bytes.

char arr[] = "some string"; 

Is it possible to change lenght of this arr variable and notify compiler how much it should free when delete variable?

I think you mean the size of the object. No, you can not change the size of the object because it was not you who allocated the memory for the object.

You could reallocate the object if you used the operator new to allocate it as for example

char *arr = new char[12];

std::strcpy( arr, "some string" );

//...

char *tmp = new char[20];

strcpy( tmp, "another " );
strcat( tmp, arr );

delete [] arr;
arr = tmp;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335