Übungsaufgabe C/C++ pointer ?malloc?

Schnelle objektorientierte, kompilierende Programmiersprache.
Wissenslücke
Beiträge: 37
Registriert: Mo Feb 22, 2016 6:03 pm

Übungsaufgabe C/C++ pointer ?malloc?

Beitrag von Wissenslücke » Mo Aug 08, 2016 7:50 pm

hallo,
ich komm mir ein wenig schäbig dabei vor aber ich muss nach zahlreichen Fehlschlägen das Forum hier mal um Rat fragen.
Your function is given an array of numbers (and its length in C/C++). Return a new array with exactly 2 elements: the first element of the given array and the last element of the given array.

Es ist also eine leere Funktion gegeben, deren Rückgabewert von der Seite(mit der Aufgabe) nach Richtigkeit geprüft wird. Würd mich freuen wenn sich jemand dran versucht.

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Übungsaufgabe C/C++ pointer ?malloc?

Beitrag von mfro » Mo Aug 08, 2016 8:38 pm

Zeig' mal, was Du bislang versucht hast.


Von hier: http://www.mycodeschool.com/work-outs/w ... unctions/5 ?

Die Aufgabe an sich ist einigermaßen doof. Wenn man sie wörtlich nimmt, gibt es keine wirklich korrekte Lösung.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Wissenslücke
Beiträge: 37
Registriert: Mo Feb 22, 2016 6:03 pm

Re: Übungsaufgabe C/C++ pointer ?malloc?

Beitrag von Wissenslücke » Di Aug 09, 2016 12:07 am

ja genau das ist die seite. wusste nicht ob ich das hier posten darf. hier mein code.

Code: Alles auswählen

/* Your includes go here */

int* boundary(int* numbers, int* Length)
{
    int newa[2]={};
    newa = malloc(sizeof(int));
    
    *Lenght-= 1;
    
   newa[0]=*numbers[0];
   newa[1]=*numbers[*Length];
    
  
    return &newa;
    
}
warum ist der rückgabetyp eigentlich ein pointer, aber beim return befehl gibt er eine adresse, also quasi ein int wert zurück.( das hab ich aus dem video übernommen, auch nehme ich an, dass 2 adressen als parameter aus main übergeben worden sind, wie im video)

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Übungsaufgabe C/C++ pointer ?malloc?

Beitrag von mfro » Di Aug 09, 2016 8:16 am

Wie schon gesagt, meines Erachtens ist die Aufgabe an sich schon Kappes. Sie will vermitteln, daß man in C eben kein Array als Returnwert zurückliefern *kann* und verlangt dann genau das. Das *muß* bei Anfängern schief gehen.
Wissenslücke hat geschrieben:

Code: Alles auswählen

int* boundary(int* numbers, int* Length)
Daß Du da einen Zeiger auf int zurückgibst, ist streng genommen verkehrt. Du sollst ein Array zurückgeben (aber das geht ja nicht). Das muß meiner Ansicht nach bei Anfängern zu heilloser Verwirrung führen.

Warum übergibst Du Length als Zeiger auf ein int? Die Aufgabenstellung verlangt eigentlich int.

Code: Alles auswählen

{
    int newa[2]={};
    newa = malloc(sizeof(int));
Hier erzeugst Du ein Array auf dem Stack (lokale Variable) und initialisierst es leer. Gleich anschließend überschreibst Du den Zeiger (merke: Arrays werden zwar über einen Zeiger auf ihr erstes Element angesprochen, Arrays und Zeiger sind aber nicht dasselbe) mit einem, den Du von malloc() zurückbekommen hast. Der Compiler wird das unnötige erste Array zwar wahrscheinlich wegoptimieren (schließlich kannst Du ja nicht mehr darauf zugreifen, weil Du den Zeiger überschrieben hast), schön ist das aber trotzdem nicht.

Dein malloc()-Aufruf reserviert nur Speicher für ein int, Du brauchst aber zwei!

Nebenbei fehlt hier was: wer malloc() aufruft, muß immer auch den Returnwert auf NULL prüfen (schließlich kann es immer sein, daß kein Heapspeicher mehr verfügbar ist, wenn Du dann einfach weitermachst, kracht's!

Code: Alles auswählen

    int *newa = malloc(sizeof(int) * 2);
    if (newa != NULL) {
        ....
    }
    else
        return NULL;
Natürlich muß der Aufrufer das wissen und im Fall der Fälle mit der NULL zurechtkommen, sonst kracht's auch.
Wissenslücke hat geschrieben:

Code: Alles auswählen

   newa[0]=*numbers[0];
   newa[1]=*numbers[*Length];
Hier sieht man, daß den Aufgabenstellern offensichtlich gelungen ist, was sie bezwecken wollten: Du bist verwirrt ;). numbers ist ein Array aus int, wie kriegt man da das 0-te und das "Length"-te Element?

Code: Alles auswählen

    newa[0] = numbers[0];
    newa[1] = numbers[*Length];

Die nächste Zeile ist leider auch verkehrt. Du willst einen Zeiger zurückgeben (newa ist schon einer), gibst aber stattdessen die Adresse dieses Zeigers zurück (was effektiv einen Zeiger auf einen Zeiger darstellt). Das ist an sich schon falsch, hier aber doppelt: newa ist eine lokale Variable, die beim Verlassen der Funktion nicht mehr gültig ist. Die Adresse davon dann natürlich erst recht nicht.
Wissenslücke hat geschrieben:

Code: Alles auswählen

  
    return &newa;
}

Code: Alles auswählen

    return newa;
Jetzt mußt Du meine korrigierten Codefitzel nur noch richtig zusammenbauen und hast eine Lösung im Sinne der Aufgabensteller (wie gesagt, ich bin der Ansicht, daß die Aufgabe schon Quatsch ist).

Tip: schalte bei deinem Compiler alle Warnungen ein, lies' und versteh' sie. Dann beseitigst Du eine nach der anderen. Compiler kennen die C-Syntax besser als die meisten Programmierer, jedenfalls besser als ein Anfänger. Insbesondere der sollte darauf hören!


Ich hätte die Aufgabe übrigens ganz frech (und meiner Ansicht nach richtiger, aber wahrscheinlich im Sinne der Aufgabensteller falsch) kurz und bündig so beantwortet:

Code: Alles auswählen

struct areturn
{
    int arr[2];
};

struct areturn boundary(int arr[], int length)
{
    struct areturn ret = { arr[0], arr[length - 1] };

    return ret;
}
Das gibt zwar nicht direkt ein Array zurück, aber ein solches in eine struct verpackt (der Aufrufer muß es nur noch auspacken). Das ist in C erlaubt, die meisten Leute nutzen es aber nicht, weil es ineffektiv ist, große Strukturen über den Stack zurückzugeben. Hier finde ich es nicht verkehrt, zwei int's über den Stack müssen immer gehen. Die Lösung erspart den Umgang mit Heap-Speicher und die dafür notwendige Fehlerbehandlung.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Wissenslücke
Beiträge: 37
Registriert: Mo Feb 22, 2016 6:03 pm

Re: Übungsaufgabe C/C++ pointer ?malloc?

Beitrag von Wissenslücke » Di Aug 09, 2016 9:44 am

man that shit goes deep. ähm ja danke erstmal für die hinweise, ich werd versuchen sie umzusetzen. dein struct konzept ist sicher richtig aber das ist wie du selbst schon sagtest wahrscheinlich nicht gesucht. der ersteller gibt noch einen hinweis:
In C/C++, You cannot create array as a local variable and return it. You need to use malloc or new operator to create it in dynamic memory.

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Übungsaufgabe C/C++ pointer ?malloc?

Beitrag von mfro » Di Aug 09, 2016 4:30 pm

Nun, das liegt wohl daran, daß nicht alles, was so als Tutorial im Internet unterwegs ist, auch perfekt ist.

Ich vergaß zu erwähnen: meine Lösung (habe ich gerade aus Spaß mal ausprobiert, 100 Millionen mal in einer Schleife) ist 32x schneller (0,6 s anstatt etwa 21) als die mit malloc() und free() ...
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Übungsaufgabe C/C++ pointer ?malloc?

Beitrag von Xin » Di Aug 09, 2016 6:22 pm

Wissenslücke hat geschrieben:man that shit goes deep. ähm ja danke erstmal für die hinweise, ich werd versuchen sie umzusetzen. dein struct konzept ist sicher richtig aber das ist wie du selbst schon sagtest wahrscheinlich nicht gesucht. der ersteller gibt noch einen hinweis:
In C/C++, You cannot create array as a local variable and return it. You need to use malloc or new operator to create it in dynamic memory.
Den Hinweis verstehe ich so, dass Du keine struct verwenden sollst (auf dem Weg war ich beim Lesen nämlich erstmal auch unterwegs), sondern ein int * zurückgibst.

Das ist zwar langsamer, wie mfro richtig gemessen hat, aber darum geht's wohl gerade nicht.

Wenn Du Dir Speicher mit malloc holst, musst Du den natürlich auch wieder freigeben. Da Du die Adresse zurückgeben musst, kannst Du das natürlich nur noch da machen, wo die Adresse dann landet.

Poste mal den dann kompletten Code.
Wissenslücke hat geschrieben:hallo,
ich komm mir ein wenig schäbig dabei vor aber ich muss nach zahlreichen Fehlschlägen das Forum hier mal um Rat fragen
Das Forum ist nicht installiert worden, damit sich keiner traut.
Die Signatur habe ich nicht umsonst da stehen. So viele Leute, die Fragen haben, aber Angst, sie "öffentlich" zu stellen.
Stell Deine Fragen, bemüh Dich darum, uns die Antwort leicht zu machen und keiner hat ein Problem damit.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Wissenslücke
Beiträge: 37
Registriert: Mo Feb 22, 2016 6:03 pm

Re: Übungsaufgabe C/C++ pointer ?malloc?

Beitrag von Wissenslücke » Fr Aug 12, 2016 8:33 pm

hey ho,

ich wollte das jetzt mal mit main versuchen damit ich besser versteh wie das läuft. ich bekomm leider eine fehlermeldung aus der ich nicht wirklich schlau werde :
error: unknown type name 'length'
plus eine warnung :
warning: initialization makes pointer from integer without a cast
. die warnung ist denk ich entweder weil der compiler der fkt nicht vertraut, dass sie eine adresse zurück gibt oder weil die adresse eventuell größer als ein int ist. bei der error message weiss ich überhaupt garnet was der von mir will. hier mein code:

Code: Alles auswählen

int bungabunga(numbers[], length)
{
    int newa[2]={};

    newa = malloc(sizeof(int)*2);

    if (newa!= 0)
    {
    newa[0]=numbers[0];
    newa[1]=numbers[length-1];
    }
    else
    {
        return NULL;
    }

    return newa;
}

int main ()
{
   int array[4]={1,2,3,4};

   int length=sizeof(array)/sizeof(array[0]);

   int* zeiger= bungabunga(array,length);

   printf(" %d %d ",*zeiger, zeiger[1]);
   return 0;


}

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Übungsaufgabe C/C++ pointer ?malloc?

Beitrag von Xin » Fr Aug 12, 2016 9:39 pm

Wissenslücke hat geschrieben:hey ho,

ich wollte das jetzt mal mit main versuchen damit ich besser versteh wie das läuft. ich bekomm leider eine fehlermeldung aus der ich nicht wirklich schlau werde :
error: unknown type name 'length'

Code: Alles auswählen

int bungabunga(numbers[], length)
Naja... in C heißt es erst Datentyp und dann Variablenname. Mich wundert eher, dass er numbers[] nicht schon bemängelt hat.
Wissenslücke hat geschrieben: plus eine warnung :
warning: initialization makes pointer from integer without a cast

Code: Alles auswählen

   int* zeiger= bungabunga(array,length);
bungabunga gibt ein int zurück und Du weißt es auf ein int * zu.


Liest Du das Tutorial auf proggen.org oder etwas anderes?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Wissenslücke
Beiträge: 37
Registriert: Mo Feb 22, 2016 6:03 pm

Re: Übungsaufgabe C/C++ pointer ?malloc?

Beitrag von Wissenslücke » Fr Aug 12, 2016 10:51 pm

Naja... in C heißt es erst Datentyp und dann Variablenname. Mich wundert eher, dass er numbers[] nicht schon bemängelt hat.
heißt das, dass der datentyp aus main nicht übernommen wird sondern nur der wert ? ist das was in den klammern steht (parameter) als initialisierung der lokalen variablen zu sehen ? das würde bei pointern ja eine rolle spieln.
bungabunga gibt ein int zurück und Du weißt es auf ein int * zu.

ach so ist das. jetzt versteh ich. ich dachte der rückgabetyp bezieht sich auf den return wert, was aus meiner sicht auch irgendwie logischer wäre ö.O
Liest Du das Tutorial auf proggen.org oder etwas anderes?
ich hab damit als ich angefangen habe zumindest begonnen ja. ich glaube bei dem zeiger sowie auch bei anderen konzepten fehlte mir wenn ich mich recht erinnere der konkrete anwendungsbereich bzw konkrete probleme in der softwareentwicklung, die mit zeigern gelöst werden. das ist aber auch schon ein wenig her also steinigt mich bitte net wenn ich hier was falsches sage. ich hab inzwischen ca 25 seiten auf in meinem browser die sich der informatik zuwenden. ich hab auch ein c++ buch durchgelesen, aber ohne regelmäßig selbst zu coden lernt man das einfach net.

habs gerade versucht mit pointer als rückgabetyp und int vor den parametern, will trotzdem nicht laufen. das ist vielleicht ein wenig dreist aber könnte nicht einer von euch profis das kleine programm fix richtig schreiben mit malloc ( ich weiss man macht das normalerweise mit struct, aber darum gehts hier nicht ;D ) und hier posten anstatt dieses ewige Hin und Her?

Antworten