Короче говоря, у меня есть программа на C++, состоящая из класса Car с подклассами SportsCar и SUV, а также CarInventory, которая хранит объекты Car.Сегментация Fault 11 в C++ при доступе к второму элементу в массиве
ответ
Я думаю, что проблема в функции вставки
void CarInventory::insert(Car *car) {
for (int i = 0; i < inventorySize; i++) {
if (carArray[i]) {
i++;
}
Когда вы найдете Автомобиль уже в вашем carArray
Increase i
, но тогда вы увеличиваете значение i
снова в for-loop. Таким образом, вы пропустите любую другую позицию в массиве, и они останутся неинициализированными.
Это было Бо. Ха-ха, я должен был это увидеть. Я использовал продолжение; вместо i ++, и это сработало. – ElGatoGabe
Я думаю, есть еще одна опасность в том, как OP добавляет элементы в свой инвентарь. Он выделяет объекты «Car» в стеке и вставляет их как '& obj', который является адресом ** стека **. Эти адреса стека остаются действительными только до тех пор, пока сама функция не вернется. После этого «Автомобиль в стеке» попадает в него, и в конечном итоге он будет иметь недопустимые адреса в контейнере, что приведет к segfaults. То, что он должен сделать, это создать «Автомобиль» в куче, используя «новый» оператор, и обязательно очистите экземпляры «Car», когда «CarInventory» будет уничтожен. – ray
Вы назначили массив из 10 автомобилей. Но вы только инициализировали его 4 автомобилями.
Так что, когда ваша петля в displayVehichles
обойдется, чтобы получить доступ к carArray[5]
, она, скорее всего, получит доступ к неинициализированной памяти.
Это утверждение кажется хлопотным:
carArray = new Car *[maxStock];
Это, вероятно, следует:
carArray = new Car *[maxStock];
for (int i = 0; i < maxStock; i++)
{
carArray[i] = NULL;
}
totalNumCars = 0;
Таким образом, ваш метод вставки будет вести себя правильно. Но ваш метод вставки может быть гораздо проще:
void CarInventory::insert(Car *car) {
if (totalNumCars < maxStock)
carArray[totalNumCars] = car;
totalNumCars++;
}
}
Далее, в то время как это нормально так, как вы его автомобилей вы заявили выходить за рамки, прежде чем ваш CarInventory выходит из области видимости, это будет ссылки объектов автомобилей, которые уже удалены.
Использование станд :: вектор держать свои автомобили:
class CarInventory
{
std::vector<Car*> _cars;
public:
void displayVehicles()
{
for (auto i = _cars.begin(); i != _cars.end(); i++)
{
i->printInfo();
}
}
void insert(Car* car)
{
_cars.push_back(car);
}
};
Теперь, по-прежнему не решает проблему своего класса CarInventory, держась указатели объектов стека.
Это даже лучше:
class CarInventory
{
std::vector<std::shared_ptr<Car>> _cars;
public:
void displayVehicles()
{
for (auto i = _cars.begin(); i != _cars.end(); i++)
{
i->printInfo();
}
}
void insert(std::shared_ptr<Car>& spCar)
{
_cars.push_back(spCar);
}
};
Тогда ваш код, чтобы использовать класс:
std::shared_ptr<Car*> createCar(const char* vin, const char* make, const char* color, int year)
{
Car* car = new Car(vin, make, color, year);
return std::shared_ptr<Car>(car);
}
int main(int argn, char *argv[])
{
CarInventory cars;
std::shared_ptr<Car*> toyota = createCar("2GCGC34M9F1152828", "Toyota", "Camry", "Green", 2012);
std::shared_ptr<Car*> honda = createCar("1C4BJWAG4DL602733", "Honda", "Civic", "Blue", 2015);
...
CarInventory cars;
cars.insert(toyota);
cars.insert(honda);
cout << "\n";
cars.displayVehicles();
}
* «Автомобили, о которых вы заявили, выходят за рамки до того, как ваш CarInventory выходит из сферы действия» * - не верно ... функции-локальные автоматические переменные «разрушаются» в противоположном направлении к объявлению/построению. –
@TonyD - Правильно. Я просто указываю, что если его переменная «carsInventory» живет самими автомобилями - потому что она во внешнем пространстве, у него будут проблемы. Я управляю его ссылкой на класс shared_ptr. – selbie
Привет, Селби, большое спасибо за помощь. Этот проект требует, чтобы я использовал массив указателей для указателей на автомобили. Есть ли способ сделать это с помощью массива? Я попытался выделить массив из 4 автомобилей, и я все еще получаю ошибку ошибки сегментации. – ElGatoGabe
- 1. C Сегментация Fault: 11
- 2. Сегментация Fault 11 с C в терминале
- 3. Сегментация Fault: 11
- 4. Сегментация Fault 11 redux
- 5. OSX Сегментация Fault 11 - Android
- 6. Weird zsh Сегментация Fault 11
- 7. Сегментация Fault 11 Ошибка Выход
- 8. Сегментация Fault 11 с рекурсивной функцией в C
- 9. сегментация 11 в C
- 10. Сегментация Fault 11, Xcode 8.2.1, Swift 3
- 11. Сегментация Fault 11 в C++ текстовой обработки файла
- 12. Xcode - Компиляция Swift Сегментация Fault 11
- 13. Сегментация Printf Fault C
- 14. Массив Сегментация Fault C
- 15. Сегментация Fault Указатели C++
- 16. Сегментация Fault chkstk_ms C++
- 17. Сегментация Fault C++
- 18. C++ Сегментация Fault linkedLists
- 19. Сегментация Fault C++ Sundaram
- 20. Virtualenv все перепутались - Сегментация Fault: 11
- 21. конца массива Сегментация Fault
- 22. C Сегментация Ошибка при доступе к индексу массива char
- 23. Таинственная Сегментация Fault в коде C++
- 24. C++ Hexadecimal Умножение Сегментация Fault
- 25. Сегментация faul при доступе к массиву 2d?
- 26. Getter и сегментация Fault
- 27. Непонятная Сегментация Fault с C++
- 28. C Сегментация Fault structs/pointers
- 29. Сегментация Fault query
- 30. mkoctfile Сегментация Fault
Как выглядит ваш метод 'insert'? – rems4e
Почему ваша функция 'insert' принимает указатели? Почему вы строите кучу автомобилей в стеке, когда хотите, чтобы они принадлежали классу? Является ли 'inventorySize' предполагаемым числом автомобилей, которые вы на самом деле имеете? Если да, то где это значение? Если нет, то почему вы печатаете много автомобилей? –
Размер инвентаря представляет собой максимальное количество автомобилей, которые могут быть в инвентарном запасе. Я добавлю свой метод вставки к своему оригинальному сообщению. Я очень новичок в C++, поэтому указатели - это то, с чем я борюсь довольно много. – ElGatoGabe