2015-10-05 1 views
-1

Короче говоря, у меня есть программа на C++, состоящая из класса Car с подклассами SportsCar и SUV, а также CarInventory, которая хранит объекты Car.Сегментация Fault 11 в C++ при доступе к второму элементу в массиве

+2

Как выглядит ваш метод 'insert'? – rems4e

+1

Почему ваша функция 'insert' принимает указатели? Почему вы строите кучу автомобилей в стеке, когда хотите, чтобы они принадлежали классу? Является ли 'inventorySize' предполагаемым числом автомобилей, которые вы на самом деле имеете? Если да, то где это значение? Если нет, то почему вы печатаете много автомобилей? –

+0

Размер инвентаря представляет собой максимальное количество автомобилей, которые могут быть в инвентарном запасе. Я добавлю свой метод вставки к своему оригинальному сообщению. Я очень новичок в C++, поэтому указатели - это то, с чем я борюсь довольно много. – ElGatoGabe

ответ

1

Я думаю, что проблема в функции вставки

void CarInventory::insert(Car *car) { 
    for (int i = 0; i < inventorySize; i++) { 
     if (carArray[i]) { 
      i++; 
     } 

Когда вы найдете Автомобиль уже в вашем carArray Increase i, но тогда вы увеличиваете значение i снова в for-loop. Таким образом, вы пропустите любую другую позицию в массиве, и они останутся неинициализированными.

+0

Это было Бо. Ха-ха, я должен был это увидеть. Я использовал продолжение; вместо i ++, и это сработало. – ElGatoGabe

+0

Я думаю, есть еще одна опасность в том, как OP добавляет элементы в свой инвентарь. Он выделяет объекты «Car» в стеке и вставляет их как '& obj', который является адресом ** стека **. Эти адреса стека остаются действительными только до тех пор, пока сама функция не вернется. После этого «Автомобиль в стеке» попадает в него, и в конечном итоге он будет иметь недопустимые адреса в контейнере, что приведет к segfaults. То, что он должен сделать, это создать «Автомобиль» в куче, используя «новый» оператор, и обязательно очистите экземпляры «Car», когда «CarInventory» будет уничтожен. – ray

1

Вы назначили массив из 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(); 
} 
+0

* «Автомобили, о которых вы заявили, выходят за рамки до того, как ваш CarInventory выходит из сферы действия» * - не верно ... функции-локальные автоматические переменные «разрушаются» в противоположном направлении к объявлению/построению. –

+0

@TonyD - Правильно. Я просто указываю, что если его переменная «carsInventory» живет самими автомобилями - потому что она во внешнем пространстве, у него будут проблемы. Я управляю его ссылкой на класс shared_ptr. – selbie

+0

Привет, Селби, большое спасибо за помощь. Этот проект требует, чтобы я использовал массив указателей для указателей на автомобили. Есть ли способ сделать это с помощью массива? Я попытался выделить массив из 4 автомобилей, и я все еще получаю ошибку ошибки сегментации. – ElGatoGabe

Смежные вопросы