Проблема с созданием аналога SetLength на C++

372
06 января 2017, 10:28

Пытаюсь сделать аналог SetLength (паскаль) в C++ Просто уже нет сил без такой же удобной вещи, но мой код почему-то не работает Вот код:

#include <iostream>
#include <cstdlib>
#include <stdlib.h>
#include <cstring>
#include <clocale>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
template <typename T>
void SetL(T * array, int newLen)
{
    int Len = sizeof(array)/sizeof(array[0]);
    void *ptrArray;
    int LenCell = sizeof(array[0]);
    if (Len ==1 )
    {
        ptrArray= calloc(newLen,LenCell);
        if (ptrArray!=NULL)  
            {
                array=memcpy(ptrArray,array,sizeof(array));
            }
        }   
}
int main(int argc, char** argv) 
{
    setlocale( LC_ALL,"Russian" );
    int n;
    cout<<"Äëèíó ìàññèâà a ââåäè\n";
    cin>>n;
    int a[n];
    SetL(a,n+5);
    cout<<sizeof(a)/sizeof(a[0]);
    system("pause");
    return 0;
}

Ошибка:

1) In instantiation of 'void SetL(T*, int) [with T = int]':
2) [Error] invalid conversion from 'void*' to 'int*' [-fpermissive]

Среда разработки: Dev-C++

Answer 1

Стандарт языка С++ не разрешает объявлять массивы переменной длины, как это имеет место в вашей программе

cin>>n;
int a[n];

Хотя некоторые компиляторы имеют собственные расширения языка, которые включают в себя возможность создавать массивы переменной длины, тем не менее лучше не пользоваться этими расширениями языка, так как код не будет удовлетворять стандарту С++, и тем самым будет не переносим и зависеть от конкретного компилятора и его настроек.

Кроме того массивы являются неизменяемыми lvalue, это означает, что вы не можете присвоить массиву другое значение. Так что ваш код в любом случае не имеет смысла.

В этой функции

template <typename T>
void SetL(T * array, int newLen)

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

Данное предложение

int Len = sizeof(array)/sizeof(array[0]);

не вычисляет количество элементов в исходном массиве, как вы, по всей видимости, думаете. array - это указатель, имеющий объявление T * array, Указатели в общем случае имеют размер либо 4 байта, либо 8 байтов в зависимости от используемой платформы. Значение выражения sizeof(array[0]) для данного вызова функции эквивалентно выражению sizeof( int ) и также может быть равно либо 4 либо 8 байтам. То есть вы всегда будете получать значения для выражения sizeof(array)/sizeof(array[0]) либо 1 либо 2 независимо от того, сколько элементов имеет исходный массив, переданный в функцию в качестве аргумента.

Так как переменная array - это локальная переменна функции, которая прекратит свое существование после выхода из функции, то имеет место утечка памяти, так как адрес динамически выделенной памяти будет утерян, и память не будет освобождена.

Что касается сообщения об ошибке компилятора, то она относится к предложению

array=memcpy(ptrArray,array,sizeof(array));

Возвращаемое значение функции memcpy имеет тип void *, которое нельзя без явного приведения типов присвоить указателю типа int *, то есть переменной array.

Кроме того лучше использовать оператор new для выделения памяти в C++, чем стандартные функции C типа malloc или calloc.

Если вам нужны массивы переменной длины, то используйте стандартный класс std::vector, объявленный в заголовке <vector>.

Например,

std::vector<int> a( n );
//...
a.resize( n + 5 );
READ ALSO
оздал TEdit динамически, не могу в него ничего писать в программе, даже выделить не могу

оздал TEdit динамически, не могу в него ничего писать в программе, даже выделить не могу

Создал TEdit динамически, не могу в него ничего писать в программе, даже выделить не могу

387
Размещения без повторений,c++

Размещения без повторений,c++

Есть код размещений с повторениями,не могу понять реализацию алгоритма без повторений,везде нахожу что нужна функция аля"NextSet",которая бы как...

362
Подключение ffmpeg в NetBeans

Подключение ffmpeg в NetBeans

Не получается слинковать ffmpeg библиотеки в NetBeansУказал путь для дополнительных библиотек, указал сами библиотеки, а в результате undefined reference:

308
Класс без данных

Класс без данных

Помогите понять, что собой представляет класс без данных, и где его можно/нужно использовать

372