Rückgabe dieses Zeigers von einer Funktion

Lesezeit: 5 Minuten

Benutzeravatar von user567879
Benutzer567879

Ich versuche, einen Zeiger von einer Funktion zurückzugeben. Aber ich erhalte einen Segmentierungsfehler. Jemand bitte sagen, was mit dem Code falsch ist

#include <stdio.h>

int *fun();

main()
{
    int *ptr;
    ptr = fun();
    printf("%d", *ptr);
}

int *fun()
{
    int *point;
    *point = 12;
    return point;
}

  • Die wichtigste Frage beim Umgang mit Zeigern ist: Zeiger auf was? Ein lokales Objekt? Kaboom. Ein dynamisch zugewiesenes Objekt? Von wem befreit? Ein Objekt woanders gespeichert? Wie lange lebt dieses Objekt dann und wie lange ist mein Zeiger gültig? Das Zurückgeben eines Zeigers von einer Funktion ist besonders riskant, da der Zeiger in einem völlig anderen Codestück initialisiert wird (das für den Aufrufer oft nicht einmal sichtbar ist) und die Aufrufer nicht wissen, wie sie mit dem Ergebnis umgehen sollen. Eine gute Dokumentation für solche Funktionen ist sehr wichtig.

    – sbi

    13. Oktober 2011 um 13:47 Uhr

  • Denken Sie nur daran, alle Objekte, Zeiger und Datenstrukturen immer zu mallocieren. Wenn Sie dies nicht tun, erhalten Sie immer einen Segmentierungsfehler, weil er nur besagt, dass wir Ihnen keinen Speicherplatz zuweisen.

    – Kevin

    13. Oktober 2011 um 14:07 Uhr

  • Wenn Sie “Fehler im Code ändern”, machen Sie die Antwort (teilweise) unabhängig von der Frage. Der fragliche Code ist nicht perfekt, das ist der Grund für die Frage. Ich empfehle dringend, in Fragen keinen Code zu korrigieren.

    – Harfner

    30. Mai 2014 um 17:29 Uhr

  • Hallo, was genau ist der Unterschied zwischen do it through malloc und mache es gerne *ptr = 12? Warum gibt ersterer einen gültigen Zeiger an den Aufrufer zurück, selbst wenn er lokal im Absender deklariert ist, während letzterer dies nicht tut?

    – SexyBeast

    3. Oktober 2015 um 12:30 Uhr

  • @AttitudeMonger Weil malloc sagt “Ich möchte etwas Speicher, um Sachen darin zu speichern”, aber einfach alt *ptr = 12 sagt “Ich möchte etwas Speicher, um eine Berechnung durchzuführen, die später für andere Dinge verwendet werden kann”.

    – wizzwizz4

    9. April 2016 um 10:46 Uhr

Weisen Sie Speicher zu, bevor Sie den Zeiger verwenden. Wenn Sie keinen Speicher zuweisen *point = 12 ist undefiniertes Verhalten.

int *fun()
{
    int *point = malloc(sizeof *point); /* Mandatory. */
    *point=12;  
    return point;
}

Auch dein printf ist falsch. Sie müssen dereferenzieren (*) der Zeiger.

printf("%d", *ptr);
             ^

  • Wenn mehr als ein Wert gespeichert werden muss, was würde ich tun? Muss ich alle zuordnen oder kann ich nur den Zeiger erhöhen?

    – Benutzer567879

    15. Oktober 2011 um 1:42 Uhr

  • @ user567879 Du musst malloc mehr Platz. Etwas wie int *point = malloc(num_values * sizeof *point);

    – Cnicutar

    15. Oktober 2011 um 6:30 Uhr

  • Ebenfalls int *point = calloc(num_values,sizeof(int)) wird nützlich sein. Mehr Infos unter thinkage.ca/english/gcos/expl/c/lib/calloc.html

    – gewaltig

    6. August 2013 um 8:42 Uhr


  • Ist es eine gute Praxis, einen Zeiger von einer Funktion zurückzugeben und das Hauptprogramm dazu zu bringen, den Speicher freizugeben? Irgendeine andere Alternative dazu? (nur falls es keine gute Praxis ist)

    – Mahesha Padyana

    27. Juli 2015 um 17:32 Uhr

  • @cnicutar: Es wäre besser, wenn Sie das Ergebnis von malloc (in int *) umwandeln würden, obwohl dies in C nicht erforderlich ist.

    – Destruktor

    19. August 2015 um 13:06 Uhr

Obwohl es eine schlechte Praxis ist, einen Zeiger auf ein lokales Objekt zurückzugeben, hat es hier nicht den Kaboom verursacht. Hier ist der Grund, warum Sie einen Segfault erhalten haben:

int *fun()
{
    int *point;
    *point=12;  <<<<<<  your program crashed here.
    return point;
}

Der lokale Zeiger verlässt den Gültigkeitsbereich, aber das eigentliche Problem besteht darin, einen Zeiger zu dereferenzieren, der nie initialisiert wurde. Was ist der Punktwert? Wer weiß. Wenn der Wert keinem gültigen Speicherplatz zugeordnet wurde, erhalten Sie einen SEGFAULT. Wenn es glücklicherweise etwas Gültiges zugeordnet ist, haben Sie gerade den Speicher beschädigt, indem Sie diese Stelle mit Ihrer Zuweisung zu 12 überschrieben haben.

Da der zurückgegebene Zeiger sofort verwendet wurde, könnten Sie in diesem Fall mit der Rückgabe eines lokalen Zeigers davonkommen. Dies ist jedoch eine schlechte Praxis, da das Verhalten des Programms undefiniert wäre, wenn dieser Zeiger wiederverwendet würde, nachdem ein anderer Funktionsaufruf diesen Speicher im Stapel wiederverwendet hat.

int *fun()
{
    int point;
    point = 12;
    return (&point);
}

oder fast identisch:

int *fun()
{
    int point;
    int *point_ptr;
    point_ptr = &point;
    *point_ptr = 12;
    return (point_ptr);
}

Eine weitere schlechte Praxis, aber sicherere Methode wäre, den ganzzahligen Wert als statische Variable zu deklarieren, und er wäre dann nicht auf dem Stapel und wäre sicher vor der Verwendung durch eine andere Funktion:

int *fun()
{
    static int point;
    int *point_ptr;
    point_ptr = &point;
    *point_ptr = 12;
    return (point_ptr);
}

oder

int *fun()
{
    static int point;
    point = 12;
    return (&point);
}

Wie andere bereits erwähnt haben, wäre der “richtige” Weg, dies zu tun, Speicher auf dem Heap über malloc zuzuweisen.

  • Und free() es nach Gebrauch.

    – C–

    3. Oktober 2018 um 6:38 Uhr

  • Wird verwendet static Kompilierungswarnungen verursachen?

    Benutzer12211554

    14. Juli 2019 um 21:46 Uhr

Benutzeravatar von Varun Chhangani
Varun Chhangani

Bei der Zuweisung des Werts 12 an den Integer-Zeiger wird kein Speicher zugewiesen. Daher stürzt es ab, weil es keinen Speicher findet.

Sie können dies versuchen:

#include<stdio.h>
#include<stdlib.h>
int *fun();

int main()
{
    int *ptr;
    ptr=fun();
    printf("\n\t\t%d\n",*ptr);
}

int *fun()
{
    int ptr;
    ptr=12;
    return(&ptr);
}

  • Existiert 12 nicht nur auf dem Stack dieses Funktionsaufrufs? Das scheint, als würde es undefiniertes Verhalten erzeugen

    – Landschaft

    3. November 2017 um 20:22 Uhr

Benutzeravatar von IdleHands_94
LeerlaufHands_94

Meines Wissens macht die Verwendung des Schlüsselworts new relativ dasselbe wie malloc(sizeof identifier). Der folgende Code zeigt, wie das Schlüsselwort new verwendet wird.

    void main(void){
        int* test;
        test = tester();
        printf("%d",*test);
        system("pause");
    return;
}
    int* tester(void){
        int *retMe;
        retMe = new int;//<----Here retMe is getting malloc for integer type
        *retMe = 12;<---- Initializes retMe... Note * dereferences retMe 
    return retMe;
}

1433620cookie-checkRückgabe dieses Zeigers von einer Funktion

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy