With the addition of subtraction displays no nonsense

Создаем вектор получаем элемент массива Выводим элемент на экран: 2 0 1 2 3 4 Сложение: 12 13 14 15 16 Вычитание: 4 5 6 7 8 Умножение: 

but when multiplying the error

 Process finished with exit code -1073741819 (0xC0000005) 

Vector.h

 #include <cstdio> #include <iostream>; class Vector{ public: //конструктор без параметров Vector(){ length=1; vector = new int*[length];//выделяем место для одного элемента vector[0]= (int *) 0;//и инициализирует его в ноль }; //конструктор с параметром Vector(int len){ if (! len < 1) { length = len; vector = new int *[length];//выделяет место аргументом for (int i = 0; i < length; i++) vector[i] = (int *) i;//инициализирует номером элемента в массиве }else{ printf("Не верное значение длинны массива"); } }; //конструктор с двумя параметрами Vector(int len,int value){ if (! len < 1) { length = len; vector = new int *[length];//выделяет место первым аргументом for (int i = 0; i < length; i++) vector[i] = (int *) value;//инициализируем вторым аргументом }else{ printf("Не верное значение длинны массива"); } }; //присваивает элементу массива некоторое значение (определить номер и новое значение элемента) int SetVectorItem(int item, int value){ if (item >=0 && item < length) vector[item] = (int *) value; } //функция которая получает некоторый элемент массива int GetVectorItem(int i){ if(i>0&&i<length){ return (int)vector[i-1]; }else{ printf("За пределами массива"); } return i; }; //Определить функцию печати. void PrintAllItems(){ for (int i = 0; i < length; i++) std::cout<<(int)vector[i]<<" "; printf("\n"); } void PrintItem(int i){ if(i>0&&i<length) printf("%i\n", vector[i-1]); } //Определить функции сложения void Add(int value){ for (int i = 0; i < length; i++) vector[i] += value;//с данными этого класса и целым числом } //Определить функции вычитания void Sub(int value){ for (int i = 0; i < length; i++) vector[i] -= value;//с данными этого класса и целым числом } //Определить функции умножения void Mul(int value){ for (int i = 0; i < length; i++) vector[i] = (int *) (*vector[i] * value);//с данными этого класса и целым числом } //Деструктор освобождает память. ~Vector(){ delete vector;// память освобождается vector = NULL;// указатель заменяется на 0 (нуль-указатель) } private: int length = 0; int **vector; int states; }; 

main.cpp

 #include <Windows.h> #include "Vector.h" int main() { SetConsoleCP(65001);// установка кодировки для ввода SetConsoleOutputCP(65001);// установка кодировки для вывода printf("Создаем вектор\n"); Vector *v1 = new Vector(5); printf("получаем элемент массива\n"); int value = v1->GetVectorItem(3); printf("Выводим элемент на экран: %i \n", value); v1->PrintAllItems(); printf("Сложение: "); v1->Add(3); v1->PrintAllItems(); printf("Вычитание: "); v1->Sub(2); v1->PrintAllItems(); printf("Умножение: "); // v1->Mul(2); // v1->PrintAllItems(); delete v1; // system("pause"); return 0; } 

    3 answers 3

    I wonder why (even this way - WHY ??? !!!! ) - did you use the int**vector ?

    In general, take. But you have a lot of horror. The constructor must either create an object or generate an exception. You have - just the output of the message.

    For some reason, in some cases you start a cycle not from scratch, in general, some oddities.

    To mix cout and printf in one program is ugly.

    And a bunch of little things ...

     class Vector{ public: //конструктор без параметров Vector(){ length=1; vector = new int[length];//выделяем место для одного элемента vector[0] = 0;//и инициализирует его в ноль }; //конструктор с параметром Vector(int len){ if (len>= 1) { length = len; vector = new int[length];//выделяет место аргументом for (int i = 0; i < length; i++) vector[i] = i;//инициализирует номером элемента в массиве }else{ printf("Неверное значение длинны массива"); //!!!! В результате вектор НЕИНИЦИАЛИЗИРОВАН!!! } }; //конструктор с двумя параметрами Vector(int len,int value){ if (len >= 1) { length = len; vector = new int[length];//выделяет место первым аргументом for (int i = 0; i < length; i++) vector[i] = value;//инициализируем вторым аргументом }else{ printf("Неверное значение длинны массива"); //!!!! В результате вектор НЕИНИЦИАЛИЗИРОВАН!!! } }; //присваивает элементу массива некоторое значение (определить номер и новое значение элемента) int SetVectorItem(int item, int value){ if (item >=0 && item < length) vector[item] = value; } //функция которая получает некоторый элемент массива int GetVectorItem(int i){ if(i>=0 && i<length){ return vector[i]; }else{ printf("За пределами массива"); } return i; }; //Определить функцию печати. void PrintAllItems(){ for (int i = 0; i < length; i++) std::cout<< vector[i] << " "; std::cout<< std::endl; } void PrintItem(int i){ if(i>=0 && i<length) std::cout << vector[i] << std::endl; } //Определить функции сложения void Add(int value){ for (int i = 0; i < length; i++) vector[i] += value;//с данными этого класса и целым числом } //Определить функции вычитания void Sub(int value){ for (int i = 0; i < length; i++) vector[i] -= value;//с данными этого класса и целым числом } //Определить функции умножения void Mul(int value){ for (int i = 0; i < length; i++) vector[i] *= value;//с данными этого класса и целым числом } //Деструктор освобождает память. ~Vector(){ delete[] vector;// память освобождается } private: int length = 0; int *vector; int states; }; int main() { printf("Создаем вектор\n"); Vector *v1 = new Vector(5); printf("получаем элемент массива\n"); int value = v1->GetVectorItem(3); printf("Выводим элемент на экран: %i \n", value); v1->PrintAllItems(); printf("Сложение: "); v1->Add(3); v1->PrintAllItems(); printf("Вычитание: "); v1->Sub(2); v1->PrintAllItems(); printf("Умножение: "); v1->Mul(2); v1->PrintAllItems(); delete v1; // system("pause"); return 0; } 
    • Thanks so much for the help))) "Mixing cout and printf in one program is ugly." I'm bad at c ++, I thought the problem was in the output method and tested different methods. "The constructor must either create an object or generate an exception. You just have to display a message." It creates an object or displays a message about an invalid parameter. If you can offer a good solution to this, then I would be grateful. I am always happy to improve my skills. "For some reason, in some cases you start a cycle not from scratch, in general, some strange things." I revised the code and did not find where it starts not from scratch. - Ghost
    • With the wrong parameters, it turns out that you can not use the object - it is not created. Its internal structure is not self-consistent, pointers indicate where it is not clear, etc. If you simply display a message, the program will still assume that this object can be used. In such a case, the exception should be gerenerted if you are still unfamiliar with them, then it is better to exit(1) or abort() program after displaying the message. About "not from scratch" - for example if(i>0&&i<length) - i.e. One item will still not be displayed ... - Harry
    • a couple more questions if you can: The problem statement still costs --------------------------------------- ------------------- In the state variable to set the error code, when there is not enough memory, goes beyond the array. Provide for the possibility of counting the number of objects of this type ------------------------------------------- --------------- For the calculation, I found this sizeof (Array) / sizeof (Array [0]) but it doesn't work - Ghost
    • Well, with each check, if something goes wrong - set this variable. Total number of objects - add static int count = 0; to the class static int count = 0; and in each constructor (you will have to write a copy) increase by 1, in the destructor - decrease. That's the counter ... - Harry

    You don't understand why, you create a vector of pointers containing invalid addresses, such as 0, and then in the Mul function you try to dereference them.

     void Mul(int value){ for (int i = 0; i < length; i++) vector[i] = (int *) (*vector[i] * value);//с данными этого класса и целым числом ^^^^^^^^^ } 

    As a result, a memory is accessed that does not belong to your program, and the program has undefined behavior. It makes no sense for your program to define a vector of pointers. It is necessary to determine the vector of integer values.

    A member of the length class should be declared as having an unsigned integer type. For example, you could declare it as size_t . Why do you yourself create difficulties by declaring this member of the class to be symbolic, so that each time you check whether the user has given a negative number?

    The state class member is not used anywhere in the class. Therefore, it can be removed from the class definition.

    For an empty vector there is no need at all to allocate memory for the elements. On about he and empty vector. Therefore, the default constructor should be declared as follows.

     Vector() : length( 0 ), vector( nullptr ) {} 

    The constructor with the parameter is initially completely incorrect.

     Vector(int len){ if (! len < 1) { length = len; vector = new int *[length];//выделяет место аргументом for (int i = 0; i < length; i++) vector[i] = (int *) i;//инициализирует номером элемента в массиве }else{ printf("Не верное значение длинны массива"); } }; 

    First, the condition in the if clause

     if (! len < 1) { ^^^^^^^^ 

    equivalent to the following condition

     if ( (! len) < 1) { ^^^^^^^^ 

    The expression !len Len will always be true when Len not 0, even if len contains a negative number. In addition, the constructor leaves the class object in an undefined state if len was equal to 0, and also has undefined behavior when len was given a negative number.

    The same is true for a constructor with two parameters.

    The SetVectorItem function SetVectorItem declared as int

     int SetVectorItem(int item, int value){ if (item >=0 && item < length) vector[item] = (int *) value; } 

    However, it returns nothing.

    Another function, the GetVectorItem function, contradicts the previous function.

     int GetVectorItem(int i){ if(i>0&&i<length){ return (int)vector[i-1]; }else{ printf("За пределами массива"); } return i; }; 

    In the first function, the argument for the index is set starting from 0

      if (item >=0 && item < length) ^^^ 

    whereas in the second function, the argument for the index is set starting at 1

      if(i>0&&i<length){ ^^^^^^^^^^^^^ 

    and besides, the last element in this case will always be unavailable. In addition, the function can return the value of i , which can only confuse the user of the function.

    The same incorrect condition for checking the index and the function PrintItem

     void PrintItem(int i){ if(i>0&&i<length) ^^^^^^^^^^^^^ printf("%i\n", vector[i-1]); } 

    So you should arrange a full revision of the class definition.

    If for some reason, for example, from training purposes, you need to create a pointer to pointers, then you should also allocate memory for each element. For example,

     Vector( size_t len ) : length( len ), vector( nullptr ) { if ( length != 0 ) { vector = new int * [length]; for ( size_t i = 0; i < length; i++ ) { vector[i] = new int( i ); } } } 
    • Thank you, very informative. And about the default constructor was the following condition. "The constructor without parameters allocates space for one element and initializes it to zero." - Ghost
    • @Ghost This is somewhat not logical, but may be the case. - Vlad from Moscow

    In general, in order not to confuse people, I will lay out a complete com

      Создать абстрактный тип данных - класс вектор (число элементов, элементы и переменная состояния). Определить конструктор без параметров, конструктор с параметром, конструктор с двумя параметрами. Конструктор без параметров выделяет место для одного элемента и инициализирует его в ноль. Конструктор с одним параметром, - количество элементов вектора, - выделяет место и инициализирует номером элемента в массиве, конструктор с двумя параметрами выделяет место (первый аргумент – количество элементов) и инициализирует вторым аргументом. Деструктор освобождает память. Определить функцию, которая присваивает элементу массива некоторое значение (определить номер и новое значение элемента), функцию которая получает некоторый элемент массива. В переменную состояния устанавливать код ошибки, когда не хватает памяти, выходит за пределы массива. Определить функцию печати. Определить функции сложения, умножения, вычитания, которые производят эти арифметические операции с данными этого класса и целым числом. Определить методы сравнения: больше, меньше или равно. Предусмотреть возможность подсчета числа объектов данного типа. Проверить работу этого класса. и то что у меня получилось, не уверен что правильно: 

    Vector.h

     #include <cstdio> #include <iostream>; static int count = 0;//Предусмотреть возможность подсчета числа объектов данного типа class Vector{ public: //конструктор без параметров Vector(){ length=1; vector = new int[length];//выделяем место для одного элемента vector[0] = 0;//и инициализирует его в ноль count++;//Увеличиваем количество объектов }; //конструктор с параметром Vector(int len){ if (len > 0) { length = len; vector = new int[length];//выделяет место аргументом for (int i = 0; i < length; i++) vector[i] = i;//инициализирует номером элемента в массиве count++;//Увеличиваем количество объектов }else{ printf("Неверное значение длинны массива"); abort(); } }; //конструктор с двумя параметрами Vector(int len,int value){ if (len > 0) { length = len; vector = new int[length];//выделяет место первым аргументом for (int i = 0; i < length; i++) vector[i] = value;//инициализируем вторым аргументом count++;//Увеличиваем количество объектов }else{ printf("Неверное значение длинны массива"); abort(); } }; //Деструктор освобождает память. ~Vector(){ delete[] vector;// память освобождается count--;//Уменьшаем количество объектов } //--------------------------------------- //присваивает элементу массива некоторое значение (определить номер и новое значение элемента) int SetVectorItem(int item, int value){ if (item >=0 && item < length) vector[item] = value; } //функция которая получает некоторый элемент массива int GetVectorItem(int i){ if(i>=0 && i<length){ return vector[i]; }else{ printf("За пределами массива"); } return i; }; //--------------------------------------- //Определить функцию печати. void PrintAllItems(){ for (int i = 0; i < length; i++) printf("%i ",vector[i]); printf("\n"); } void PrintItem(int i){ if(i>=0 && i<length) printf("%i \n",vector[i]); } //--------------------------------------- //Определить функции сложения void Add(int value){ for (int i = 0; i < length; i++) vector[i] += value;//с данными этого класса и целым числом } //Определить функции вычитания void Sub(int value){ for (int i = 0; i < length; i++) vector[i] -= value;//с данными этого класса и целым числом } //Определить функции умножения void Mul(int value){ for (int i = 0; i < length; i++) vector[i] *= value;//с данными этого класса и целым числом } //--------------------------------------- //Определить методы сравнения: //больше void Larger(int a, int b){ if (vector[a]>vector[b]) { printf("Больше\n"); } } //меньше void Less (int a, int b){ if (vector[a]<vector[b]) { printf("Меньше\n"); } } //равно void Equ (int a, int b){ if (vector[a]==vector[b]) { printf("Равно\n"); } } //--------------------------------------- //Предусмотреть возможность подсчета числа объектов данного типа. int GetCountObjectsVector(){ return count; } private: int length = 0; int *vector; int states; }; 

    main.cpp

     #include <Windows.h> #include "Vector.h" int main() { SetConsoleCP(65001);// установка кодировки для ввода SetConsoleOutputCP(65001);// установка кодировки для вывода int a,b; printf("Создаем вектор\n"); Vector *v1 = new Vector(8); printf("Введите два числа через пробел: "); std::cin>>a>>b; printf("a = %i, b = %i\n",a,b); printf("получаем элемент массива: %i \n",v1->GetVectorItem(a)); v1->PrintAllItems(); printf("Сложение: "); v1->Add(a); v1->PrintAllItems(); printf("Вычитание: "); v1->Sub(a); v1->PrintAllItems(); printf("Умножение: "); v1->Mul(a); v1->PrintAllItems(); //методы сравнения: v1->Larger(a,b); v1->Less(a,b); v1->Equ(a,b); printf("Колличество объектов: %i", v1->GetCountObjectsVector()); delete v1; // system("pause"); return 0; }