2016-03-21 10 views
0

Ich habe eine for-Schleife, die durch eine Array-Liste von Tagen zykliert und speichert ein int in Variable num, wenn ich die ersten 7 Tage durchlaufen, stürzt mein Programm ab, ich möchte es neu starten am Tag 1 und Wechsel zu Affe '1' ... aber nach der ersten Schleife stürzt es ab.für die Schleife Absturz ... segFault C++

Was mache ich falsch?

C++

//********************************************************************************************* 
//        function prototype 
//********************************************************************************************* 
void collectFood(string days[]); 



int main(){ 

    //array to hold week days 
    string days[7] = {"Mon", "Tue", "Wen", "Thur", "Fri", "Sat", "Sun"}; 

    collectFood(days); 

} 
//********************************************************************************************* 
//     function to collect foods amounts 
//********************************************************************************************* 
void collectFood(string days[]){  
    int num = 0; 

    // for loop for each monkey 
    for (int monkey=0; monkey < 3; monkey++){ 
     // for loop to take 7 days worth of food per monkey 
     for (int day=0; day < sizeof(days); day++){ 
      cout << "Enter the pounds of food eaten by monkey " << monkey 
      << " on " << days[day] << ": "; 
      cin >> num ; 
     } 
    } 
} 
+4

'sizeof (Tage);' Ich bin ziemlich zuversichtlich, dass das nicht bedeutet, was Sie denken, dass es tut. Auf einer 64-Bit-Plattform wird das ** 8 ** sein; nicht 7 (und auf einer 32-Bit-Plattform wird es nur 4 sein). Sie verwenden die Größe eines * Zeigers *, nicht die Größe Ihres Arrays. – WhozCraig

+0

Lassen Sie einfach die '7' in der Deklaration von Tagen weg, später statt 'sizeof (Tage) 'benutzen Sie' days-> length() '. –

Antwort

1

Sie Berechnung der erwarteten Größenordnung ist nicht korrekt im Kontext Sie verwenden. Ein einfaches Array vom C-Typ (das ist das, was Sie haben, unabhängig von dem darin enthaltenen Typ) drückt sich als Zeiger auf Typ aus, wenn es als einfacher Parameter übergeben wird.

Somit folgt aus:

void collectFood(string days[]) 

ist dies äquivalent:

void collectFood(string *days) 

und es wird deutlich, dass in der Tat sizeof(days) die Größe eines zustringZeiger ist. Auf Ihrer Plattform kann ich wahrscheinlich mit Sicherheit davon ausgehen, dass Sie 64-Bit-Code kompilieren, da ein Zeiger in diesem Kontext acht Bytes wäre und Sie somit die tatsächliche Größe Ihres Arrays um ein Element überschreiten würden.

Es gibt eine Vielzahl von Möglichkeiten, dies zu tun. Sie könnten einfach einen zusätzlichen Parameter für Ihre collectFood-Funktion deklarieren, der die Größe der Sequenz beschreibt.

void collectFood(string days[], size_t N) 

und verwenden N innerhalb Ihrer for-Schleife Bedingung, Aufrufen collectFood wie dies aus main():

collectFood(days, sizeof(days)/sizeof(*days)); 

Eine Alternative wäre eine Vorlage, die eine nicht typisierte Parameter aus dem Array abgeleitet erfolgt, die wird durch Referenz bestanden:

template<size_t N> 
void collectFood(string (&days)[N]) 
{ 
    ... 
} 

und u, wieder se N innerhalb der for-Bedingung als Zählgrenze. In diesem Fall würde der Anruf von main() so bleiben, wie Sie ihn jetzt haben. N würde durch den Aufruf abgeleitet werden. Als zusätzlichen Vorteil können Sie nicht versehentlich einen rohen Zeiger auf diese Funktion übergeben. es muss ein deklarierter Array-Typ sein, oder die Größe kann nicht abgeleitet werden und der Compiler wird einen Fehler ausspucken, der Ihnen das sagt.

Es gibt andere Wege, aber die ersteren, einfach die Länge zu überschreiten und es als formalen Parameter zu deklarieren, ist wahrscheinlich das einfachste für Sie zu verstehen.

Viel Glück.

+0

Ich werde ehrlich sein, einige der Sätze, die Sie verwendet haben, sind aus meiner Wissensdatenbank. Und ich habe festgestellt, dass "sizeof()" tatsächlich nicht das tut, was ich dachte. Ich hatte aus irgendeinem Grund den Eindruck, dass sizeof() mir die Länge des Arrays geben würde, und genau das wollte ich. also was ich verstehe ... dass "string * days" ein Zeiger ist, der auf die Position des Arrays zeigt, richtig? worüber ich verwirrt bin, ist "die Größe der Sequenz", indem ich einen zusätzlichen Parameter deklariere .... ich habe auch keine Ahnung von Templates, verstehe aber die Idee dessen, was es ist. – waterunnr4

+0

Wenn ich nur versuche, die Länge meines Arrays "7" zu verwenden, würde es einen einfacheren Weg geben? während das, was Sie mir gezeigt haben, ist wahrscheinlich richtig und es ist nur einen Weg aus meiner Wissensdatenbank. zum Beispiel könnte ich einfach sizeof (Tage) durch "7" ersetzen und es wird tun, was ich will, aber ich habe versucht, es so zu tun, um die Größe des Arrays zu übergeben, für zukünftige Verwendung, wenn das Array war um die Größe zu ändern und die Wissensbasis zu haben, dass, wenn mein Array nicht 7 Tage lang war, ich etwas verwenden könnte, würde die Größe des Arrays für die for-Schleife bestimmen, wenn das sinnvoll ist. – waterunnr4

+0

@ waterunnr4 Der einfachste Weg ist der * erste *, den ich Ihnen zeigte, und ist bei weitem am einfachsten zu verstehen. Wenn Sie weitere Erfahrung mit C++ haben, werden Ihnen weitere Optionen zur Verfügung gestellt, wie zum Beispiel die Template-Methode, die ich gezeigt habe. Schließlich werden Sie wahrscheinlich zu 'std :: array <>', 'std :: vector <>' usw. wechseln. Es kommt mit der Zeit. – WhozCraig

1

Ich denke, es ist Ihre innere for-Schleife, wenn Sie sizeof (Tage) verwenden. Wenn Sie das Array an eine Funktion übergeben, übergibt es nur einen Zeiger an das erste Element des Arrays, nicht das gesamte Array.

Sie können dies beheben, indem Sie einen Funktionsparameter hinzufügen, der Ihnen die Größe des Arrays mitteilt, oder Sie können zur Verwendung von std :: vector wechseln, das eine size() -Methode hat.Ich würde persönlich mit st :: vector gehen.