C ++ char array [] Speicherverlust [Duplikat]

Aug 18 2020

Ich habe char arr [] erstellt und ihm ein String-Literal zugewiesen

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'

Als nächstes setze ich Null-Terminator in 6 Element

arr[5] = '\0';
std::cout << std::strlen(arr) << std::endl; // lenght is 5 chars  + 1 null-terminator
  1. Ist es ein Speicherverlust?
  2. Woher weiß der Compiler, dass er nach dem ersten '\ 0' Speicher freigeben muss? (Wann wird die Variable arr gelöscht?)
  3. Ist es möglich, die Länge dieser arr-Variablen zu ändern und dem Compiler mitzuteilen, wie viel sie beim Löschen der Variablen freigeben soll?

Antworten

5 user253751 Aug 18 2020 at 13:03
  1. Ist es ein Speicherverlust?

Nein.

  1. Woher weiß der Compiler, dass er nach dem ersten '\ 0' Speicher freigeben muss? (Wann wird die Variable arr gelöscht?)

Die Variable ist 12 Zeichen. Es ist das gleiche wie schreiben:

char arr[12] = "some string";

Es werden also immer 12 Zeichen frei. Die Variable besteht aus 12 Zeichen. Die Tatsache, dass das 6. Zeichen zufällig '\ 0' ist, ist völlig irrelevant.

Übrigens, sobald Sie das 6. Zeichen auf '\ 0' gesetzt haben, dürfen Sie immer noch alle 12 Zeichen verwenden, da es sich immer noch um ein Array mit 12 Zeichen handelt. Sogar die nach dem '\ 0'. Sie können jedoch keine 13 Zeichen darin speichern.

  1. Ist es möglich, die Länge dieser arr-Variablen zu ändern und dem Compiler mitzuteilen, wie viel sie beim Löschen der Variablen freigeben soll?

Nein. Es ist nicht möglich, die Größe einer Variablen zu ändern.

6 cigien Aug 18 2020 at 13:03

In diesem Code:

char arr[] = "some string";

Die Variable arrist ein statisches Array mit einer festen Größe. Hier gibt es keine dynamische Speicherzuweisung, sodass Sie sich keine Gedanken über Speicherlecks machen müssen. Der Compiler kümmert sich um den Speicher, unabhängig davon, in was Sie schreiben arr.

2 JoopEggen Aug 18 2020 at 13:07

Zur Vollständigkeit.

Es gibt auch keinen Speicherverlust im zugewiesenen Speicher, wie in:

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

Die Speicherverwaltung erfolgt nach zugewiesenem Speicher (12) und nicht nach der zugrunde liegenden Verwendung (nicht terminiertes Zeichen *). (C-Stil, C ++ ebenfalls)

1 Slava Aug 18 2020 at 13:56

Sieht so aus, als hättest du es rückwärts verstanden. Die Arraygröße in C ++ kann nicht geändert werden. Aufgrund dieser Tatsache und der Tatsache, dass beim Übergeben eines Arrays als Zeiger Informationen über die tatsächliche Größe dieser Array- Vereinbarung für Zeichenfolgen im C-Stil erstellt wurden - 0 Byte, auch bekannt \0als Null-Terminator, wird als dynamisches Ende der Zeichenfolge behandelt. Übereinstimmung bedeutet, dass Funktionen, die mit Zeichenfolgen im C-Stil arbeiten, dies als Zeichenfolgenbeendigung behandeln. Auf diese Weise können Sie ein Array mit fester Größe für Zeichenfolgen unterschiedlicher Länge verwenden und nur einen Zeiger ohne Größe des tatsächlichen Speichers an Funktionen übergeben, die daraus gelesen werden können (z. B. Drucken auf dem Bildschirm). Beachten Sie, dass Sie beim Übergeben eines char-Arrays an Funktionen, die Daten in das Array schreiben, häufig die tatsächliche Arraygröße angeben müssen, damit die Funktion nicht außerhalb der Grenzen auf den Speicher zugreift, da diese Funktion den Nullterminator ignoriert, wenn er bereits vorhanden ist.

Das war's, diese Vereinbarung findet auf verschiedenen Ebenen statt, die von Arrays verwaltet werden. Unabhängig davon, welche Daten Sie in dieses Array einfügen, hat dies aus sprachlicher Sicht keinen Einfluss auf die Größe. Für den C ++ - Compiler haben Sie ein Array mit fester Größe erstellt. Sie haben einige Daten in das Array eingefügt, und wenn die Lebensdauer abgelaufen ist, zerstört der Compiler es als ganzes Array mit fester Größe. Es ist egal, ob Sie dort Null-Byte setzen oder nicht.

VladfromMoscow Aug 18 2020 at 13:16

Ein Speicherverlust tritt auf, wenn ein Speicher vom Programmierer mithilfe des Operators zugewiesen newund nicht mithilfe des Operators deleteoder gelöscht wurde delete [].

In dieser Erklärung

char arr[] = "some string"; 

Es ist der vom Compiler (oder dem System) zugewiesene Speicher für das Zeichenarray arr, der entweder die automatische Speicherdauer oder die statische Speicherdauer aufweist. Der Compiler (oder das System) ist also dafür verantwortlich, den zugewiesenen Speicher freizugeben. Die Adresse des zugewiesenen Speichers ist dem Compiler (oder dem System) bekannt.

Mit dieser Anweisung

arr[5] = '\0';

Sie haben das Array nicht neu zugewiesen. Sie haben nur den Inhalt genauer geändert, nur ein Byte.

Woher weiß der Compiler, dass er nach dem ersten '\ 0' Speicher freigeben muss? (Wann wird die Variable arr gelöscht?)

Weil der Compiler (oder das System) weiß, wie das Objekt des Array-Typs deklariert wurde.

Für das Objekt wurden 12 Bytes zugewiesen.

char arr[] = "some string"; 

Ist es möglich, die Länge dieser arr-Variablen zu ändern und dem Compiler mitzuteilen, wie viel sie beim Löschen der Variablen freigeben soll?

Ich denke du meinst die Größe des Objekts. Nein, Sie können die Größe des Objekts nicht ändern, da nicht Sie den Speicher für das Objekt zugewiesen haben.

Sie können das Objekt neu newzuweisen, wenn Sie den Operator zum Beispiel zum Zuweisen verwendet haben

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;