2016-05-08 10 views
1

Ich mache eine Schulaufgabe, ich habe ich in 2 Probleme gerannt. Ich muss Stacks mit Arrays simulieren. Meine aktuellen Code ist wie folgt: (! Empty (MyStack))C: Stack Element durch einen Funktionsaufruf überschrieben

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

typedef struct { 
    int capacity; 
    int * array; 
    int size; 
} stack_tt; 
int pop(stack_tt * stack_p); 
void push(stack_tt * stack_p, int value); 
int top(stack_tt * stack_p); 
stack_tt * newStack(void); 
int empty(stack_tt * stack_p); 

int main() { 
    stack_tt * myStack = newStack(); 
    push(myStack, 123); 
    push(myStack, 99); 
    push(myStack, 4444); 
    while (!empty(myStack)) { 
     int value; 
     value = pop(myStack); 
     printf("popped: %d\n", value); 
    } 
    return 0; } 

stack_tt * newStack(){ 
    stack_tt * newS = malloc(sizeof(stack_tt) * 20); 
    (*newS).capacity = 1; 
    (*newS).size = 0; 
    return newS; 
} 

void push(stack_tt * stack_p, int value){ 
    if ((*stack_p).size >= (*stack_p).capacity) { 
     (*stack_p).capacity*=2; 
     //realloc(stack_p, stack_p->capacity * sizeof(stack_tt)); 
    } 
    (*stack_p).array = &value; 
    (*stack_p).size++; 
} 

int pop(stack_tt * stack_p){ 
    (*stack_p).size--; 
    int fap = *(*stack_p).array; 
    return fap; 
} 

int empty(stack_tt * stack_p){ 
    if ((*stack_p).size >= 1) 
     return 0; 
    return 1; 
} 

Faust, wenn ich die Linie während nennen es den Wert in meinem Array ändert sich auf 1

zweitens bin ich Ich bin nicht in der Lage, einzelne Werte in meinem Array zu ändern, wenn ich versuche, Dinge wie: (* stack_p) .array [0] = Wert; Es weiß nicht, wo in der Erinnerung zu suchen.

stack_tt * newS = malloc(sizeof(stack_tt)); 

aber Sie müssen: Ich hoffe, dass jemand in der Lage ist, mir zu helfen :)

Antwort

0

Es gibt keine Notwendigkeit, Raum stack_tt, für 20 structs vom Typ Sie nur Platz für ein zuweisen muß zuzuordnen ist Zuweisen von Platz für Elemente des Strukturelement-Arrays:

newS->array = malloc(sizeof(int)*20); 
newS->size = 0; 
newS->capacity = 20; 

Jetzt können Sie das Array-Element verwenden.


Wenn Sie einen Wert auf den ‚Stapel‘ drücken, sollten Sie das Arraymitglied mit der Adresse der lokalen Variablen nicht überschreiben, die keinen Sinn machen und bewirkt, dass nicht definiertes Verhalten zusätzlich das zu verlieren zuvor zugewiesenen Speicher. Statt einfach den Wert auf das Element zuweisen array, in der Funktion push:

stack_p->array[stack_p->size] = value; 
stack_p->size++; 

Ähnlich, wenn Sie ein Element Pop, von dem Mitglied das aktuelle Element nehmen array:

stack_p->size--; 
int fap = stack_p->array[stack_p->size]; 

Der Rest Die Funktionen und der Code sollten auf die gleiche Weise festgelegt werden.

+0

ich das versucht habe, ich mich den Fehler gibt: 'Thread 1: EXC_BAD_ACCESS (code = 1, Adresse = 0x0)' – Klopper

+0

@ Klopper Natürlich sind die Beispiele, auf die ich hingewiesen habe, nicht die einzigen Probleme. Es ist nicht möglich, jeden Fehler aufzuzeigen, weil der Code konzeptionell falsch ist. Das gesamte Projekt muss neu geschrieben werden. Verwenden Sie die Beispiele, die ich als Leitfaden gegeben habe. – 2501

+1

Danke, ich sehe jetzt :) Das war eine große Hilfe! – Klopper

1

Es gibt ein paar Probleme mit dem Code, wie ich es sehe.

Läßt die push Funktion, wo Sie tun

(*stack_p).array = &value; 

dass die array Strukturelement Punkt zum lokalen Variable value machen wird, und sobald die Funktion die Variable aufhören kehrt existieren Sie mit einem Streu verlassen Zeiger und mit diesem Zeiger führt zu undefined Verhalten.

Das zweite Problem mit diesem Code ist, dass Ihr Stapel nur (illegal) auf das zuletzt hinzugefügte Element zeigt.

Sie müssen Speicher explizit für array reservieren und capacity verwenden, um zu verfolgen, wie viel Speicher zugeordnet ist. Die Verwendung von size als Index in das zugewiesene Array für das Schieben und Poppen.So etwas wie

stack_tt * newStack(){ 
    stack_tt * newS = malloc(sizeof(stack_tt)); // Only allocate *one* structure 
    newS->capacity = 0; // Start with zero capacity 
    newS->size = 0; 
    newS->array = NULL; 
    return newS; 
} 

void push(stack_tt * stack_p, int value){ 
    if (stack_p->size + 1 > stack_p->capacity){ 
     // Increase capacity by ten elements 
     int new_capacity = stack_p->capacity + 10; 
     int * temp_array = realloc(stack_p->array, new_capacity * sizeof(int)); 
     if (temp_srray == NULL) 
      return; 

     stack_p->capacity = new_capacity; 
     stack_p->array = temp_array; 
    } 

    stack_p->array[stack_p->size++] = value; 
} 

int pop(stack_tt * stack_p){ 
    if (stack_p->size > 0) 
     return stack_p->array[--stack_p->size]; 
    return 0; 
} 

int empty(stack_tt * stack_p){ 
    return stack_p->size == 0; 
} 
+0

Wären Sie bitte so freundlich, die folgende Bearbeitung in 'int pop()' zu akzeptieren: 'if (stack_p-> size> 0)'. Sonst bleibt es in der Endlosschleife "popped: 0" hängen. Ich habe nicht genug Rep, um das zu tun. Danke – user3078414

0

Du bist Code ist gut, aber wahrscheinlich verstehen Sie nicht die Verwendung von realloc:

//realloc(stack_p, stack_p->capacity * sizeof(stack_tt)); 

This function returns a pointer to the newly allocated memory, or NULL if the request fails.

Der realloc der Speicher zeigte (wie die Funktion schon sagt) nimmt durch den Zeiger, den Sie übergeben, und kopiert diesen Speicherblock in einem neuen und neu bemessenen Block. Also sollte der richtige Code sein.

stack_p->array = realloc(stack_p->array, stack_p->capacity * sizeof(stack_tt)); 

Diese andere Zeile ist falsch:

(*stack_p).array = &value; 

ändern es mit:

stack_p->array[stack_p->size] = value; 

Noch ein kleiner Vorschlag kann jeder (*stack_p). durch stack_p-> ersetzt werden, die mehr elegant.

In der newStack() sind Sie malloc ing 20 Strukturen, die irgendwie unbrauchbar ist. Du brauchst nur einen.

Dann sollten Sie das Array zum ersten Mal malloc:

newS->array = malloc(sizeof(int)); 
newS->capacity = 1; 
+0

Was ist los mit '(* stack_p) .' und warum sollte er' stack_p-> 'verwenden? Was ist der Vorteil des letzten? – Michi

+0

Es ist nur ein eleganter Code. Eleganter Code == besser lesbarer Code und leichter zu verstehen – NoImaginationGuy

+0

Wenn es um Zeiger geht, gibt es keine Unterschiede zwischen elegant und besser lesbar. Nur wie du sie verstehst. – Michi

Verwandte Themen