2016-03-21 4 views
0

У меня есть цикл for, который циклически проходит через список массивов дней и сохраняет int в переменной num, когда я переключаюсь через первые 7 дней, моя программа вылетает, я хочу, чтобы она перезапустилась на 1-й день и перейти к обезьяне «1» ... но после первого цикла он сработает.for loop crashing ... segFault C++

Что я делаю неправильно?

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 (days);' Я достаточно уверен, что это не значит, что вы думаете. На 64-битной платформе, которая будет ** 8 **; не 7 (а на 32-битной платформе это будет всего 4). Вы используете размер * указателя *, а не величину вашего массива. – WhozCraig

+0

Просто опустите '7' в объявлении дней, позже вместо' sizeof (days) 'use' days-> length() '. –

ответ

1

Вы расчет ожидаемой величины не является правильным в контексте вы используете. Простой массив C-типа (который у вас есть, независимо от типа внутри) выражается как указатель на тип при передаче в качестве простого параметра.

Таким образом, это:

void collectFood(string days[]) 

эквивалентно следующему:

void collectFood(string *days) 

и становится совершенно очевидно, что sizeof(days) действительно размер указателя к string. На вашей платформе я могу с уверенностью предположить, что вы компилируете 64-битный код, поскольку указатель в этом контексте будет восемь байтов, и, таким образом, вы превысите фактический размер вашего массива на один элемент.

Существует множество способов сделать это. Вы можете просто объявить дополнительный параметр своей функции collectFood, которая описывает величину последовательности.

void collectFood(string days[], size_t N) 

и использовать N в вашем для цикла состояния, вызывая collectFood как это из main():

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

Альтернатива может быть шаблоном, который принимает не-напечатал параметр, выведенный из массива, который передается по ссылки:

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

и снова, U se N в качестве условия для ограничения срока. В этом случае звонок от main() остался бы таким же, как у вас сейчас. N будет выведено по вызову. В качестве дополнительного преимущества вы не можете случайно передать необработанный указатель на эту функцию; это должно быть быть объявленным типом массива, или величина не может быть выведена, и компилятор будет извергать ошибку, сообщающую вам об этом.

Есть и другие способы, но первый из них, просто передавая длину и объявляя его формальным параметром, скорее всего, будет самым легким для вас.

Удачи.

+0

Буду честным, некоторые фразы, которые вы использовали, из моей базы знаний. И я понял, что «sizeof()» не влияет на то, что я думал. По какой-то причине у меня создалось впечатление, что sizeof() даст мне длину массива, для чего я и собираюсь. так что понимаю, что я понимаю .... что «string * days» - это указатель, который указывает на расположение массива, правильно? я смущен, это «величина последовательности», объявляя дополнительный параметр ... Я также не знаю шаблонов, но понимаю, что это такое. – waterunnr4

+0

Если я просто пытаюсь использовать длину моего массива «7», будет ли способ simpiler? в то время как то, что вы показали мне, вероятно, является правильным и продвигает свой путь из моей базы знаний. например, я мог бы просто заменить sizeof (days) на «7», и он будет делать то, что я хочу, но я пытался сделать это таким образом, чтобы передать размер массива для будущего использования, если массив был чтобы изменить размеры и иметь базу знаний, что если мой массив не был установленным 7 дней, я мог бы использовать что-то, что бы определить размер массива для цикла for, если это имеет смысл. – waterunnr4

+0

@ waterunnr4 Самый простой способ - это первый * тот, который я вам показал, и его гораздо легче понять. По мере того, как вы станете более опытными с C++, у вас будет больше вариантов, таких как метод шаблона, который я показал. В конце концов вы, скорее всего, перейдете к 'std :: array <>', 'std :: vector <>' и т. Д. Он приходит со временем. – WhozCraig

1

Я думаю, что это ваш внутренний цикл, когда вы используете sizeof (дни). Когда вы передаете массив функции, он передает только первый элемент массива, а не весь массив.

Вы можете исправить это, добавив параметр функции, который сообщает вам размер массива, или вы можете переключиться на использование std :: vector, который имеет метод size().Я бы лично пошел с std :: vector.