realloc () baumelnde Zeiger und undefiniertes Verhalten

Wenn Sie Speicher freigeben, was passiert mit Zeigern, die auf diesen Speicher verweisen? Werden sie sofort ungültig? Was passiert, wenn sie später wieder gültig werden?

Sicher, der übliche Fall, dass ein Zeiger ungültig wird und dann wieder "gültig" wird, ist ein anderes Objekt, das dem zuvor verwendeten Speicher zugewiesen wird. Wenn Sie mit dem Zeiger auf den Speicher zugreifen, ist dasoffensichtlic undefiniertes Verhalten. Dangling Pointer Memory überschreibt Lektion 1 ziemlich genau.

Aber was ist, wenn der Speicher für die gleiche Zuordnung wieder gültig wird? Dafür gibt es nur einen Standardweg:realloc(). Wenn Sie einen Zeiger auf eine Stelle innerhalb eines @ habmalloc() 'd Speicherblock am Offset> 1, dann benutzerealloc() Um den Block auf weniger als Ihren Versatz zu verkleinern, wird Ihr Zeiger offensichtlich ungültig. Wenn Sie dann @ verwendrealloc()achsen Sie den Block erneut zurück, um mindestens den Objekttyp abzudecken, auf den der baumelnde Zeiger zeigt. In beiden Fällen ist dies auch nicht der Falrealloc() Speicherblock verschieben, ist der baumelnde Zeiger wieder gültig?

Dies ist so ein Eckfall, dass ich nicht wirklich weiß, wie man die C- oder C ++ - Standards interpretiert, um es herauszufinden. Das folgende Programm zeigt es.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    static const char s_message[] = "hello there";
    static const char s_kitty[] = "kitty";

    char *string = malloc(sizeof(s_message));
    if (!string)
    {
        fprintf(stderr, "malloc failed\n");
        return 1;
    }

    memcpy(string, s_message, sizeof(s_message));
    printf("%p %s\n", string, string);

    char *overwrite = string + 6;
    *overwrite = '\0';
    printf("%p %s\n", string, string);

    string[4] = '\0';
    char *new_string = realloc(string, 5);
    if (new_string != string)
    {
        fprintf(stderr, "realloc #1 failed or moved the string\n");
        free(new_string ? new_string : string);
        return 1;
    }
    string = new_string;
    printf("%p %s\n", string, string);

    new_string = realloc(string, 6 + sizeof(s_kitty));
    if (new_string != string)
    {
        fprintf(stderr, "realloc #2 failed or moved the string\n");
        free(new_string ? new_string : string);
        return 1;
    }

    // Is this defined behavior, even though at one point,
    // "overwrite" was a dangling pointer?
    memcpy(overwrite, s_kitty, sizeof(s_kitty));
    string[4] = s_message[4];
    printf("%p %s\n", string, string);
    free(string);
    return 0;
}

Antworten auf die Frage(3)

Ihre Antwort auf die Frage