C ++ GCC 4.3.2 ошибка на векторе char-массива

Похоже в проблеме на эту ошибку

Вопрос о хранении массива в std :: vector в C ++

но по другой причине (см. ниже).

Для следующего примера программы на C ++:

#include <vector>

int main(int c_, char ** v_)
{
        const int LENGTH = 100;

        std::vector<char[LENGTH]> ca_vector;

        return 0;

}

GCC 4.2.3 компилируется чисто. GCC 4.3.2 выдает следующие ошибки:

/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h: в функции 'void std :: _ Destroy (_Tp *) [с _Tp = char [100 ]]:
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:103: создается из 'void std :: _ Destroy (_ForwardIterator, _ForwardIterator) [с _ForwardIterator = char (*) [100]] '
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:128: создается из 'void std :: _ Destroy (_ForwardIterator, _ForwardIterator, std :: allocator & & ) [с _ForwardIterator = char (*) [100], _Tp = char [100]] '
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_vector.h:300: создается из 'std :: vector :: ~ vector () [with _Tp = char [100], _Alloc = std :: allocator] '
test.cpp: 7: создается здесь
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4/bits/stl_construct.h:88: ошибка: запрос на член '~ char [100]' в '* __pointer' , который имеет неклассовый тип 'char [100]'

Причина, по-видимому, в этом немного

включают в себя / г ++ - v4 / бит / stl_construct.h 

  template
    inline void
    _Destroy(_Tp* __pointer)
    { __pointer->~_Tp(); }

который вызван, я думаю, из-за неправильного распада массива в указатель.

Мой вопрос: есть ли что-нибудь в стандарте языка, препятствующее хранению массивов в std :: vector? Или это просто ошибка в этой специальной версии GCC?

Я считаю, что это должно скомпилироваться (то есть 4.2.3 является правильным).

Спасибо мартин

13.10.2009 12:02:52
По какой причине вы не используете std :: string?
kmarsh 13.10.2009 12:07:26
Вы говорите, что ваш код правильно скомпилирован и выполнен в GCC 4.2.3?
fpmurphy 13.10.2009 12:32:03
Это все еще компилируется в этой системе, да. И это похоже на работу.
martin 13.10.2009 16:14:10
@kmarsh: я уже заменил его на std :: string (будет с самого начала); Я унаследовал этот кусок кода, но я должен признать, я бы не знал, что это незаконно (сегодня я почти никогда не использую сырые массивы); после ответов кажется вполне логичным, что это должно быть запрещено. И мне не нравится думать о том, почему это сработало до сих пор и действительно ли это сработало ...
martin 13.10.2009 16:16:47
4 ОТВЕТА
РЕШЕНИЕ

Да, что-то в стандартной остановке с использованием массивов Использование Draft C ++ 98 Standard

Раздел 23 Контейнеры

Тип объектов, хранящихся в этих компонентах, должен соответствовать требованиям типов CopyConstructible (20.1.3) и дополнительным требованиям типов Assignablety.

где компоненты представляют собой различные контейнеры

20.1.3 включает требование, чтобы тип имел деструктор.

Я думаю, что это как вектор должен копировать выделять и удалять элементы. Как C ++ знает, как копировать или удалять символ []?

6
14.10.2009 09:53:45
Спасибо за ссылку, хорошая работа. Должен был найти это сам, но был слишком тупым. Другие ответы тоже правильные, я отмечаю это, так как он был самым быстрым. С уважением Мартин
martin 13.10.2009 12:53:10
Я уверен, что вы не понимаете это. std::vector<int>очень легально, хотя у int тоже нет деструктора.
MSalters 14.10.2009 08:49:45
Вы можете сделать x = new int (5): удалить x; - но чтобы удалить массив, вам нужно удалить []
user151019 14.10.2009 09:59:17

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

1D vector  ->  std::vector<char*> ca_vector;
2D vector  ->  std::vector<char*,char*> ca_vector;
-1
13.10.2009 12:25:49
Здравствуйте, спасибо за ответ. Мне известно, что вектор можно использовать как массив, как вы правильно указали. Я хотел бы знать, является ли приведенный выше код законным в смысле стандарта. Я мог бы поместить туда вектор strings vector <string>, но, как писал Марк, базовый массив C / C ++ не удовлетворяет требованиям к элементам контейнера.
martin 13.10.2009 12:28:43
@Aykut: std :: vector <char *, char *> не имеет никакого смысла.
sellibitze 13.10.2009 12:37:37
Второй аргумент шаблона для вектора не является типом второго измерения (векторы имеют только одно измерение). Второй аргумент - это allocate (по умолчанию стандартный распределитель).
matt_h 13.10.2009 16:25:25
2D вектор будет выглядеть примерно так: std :: vector <std :: vector <char *>>
Jonas 14.10.2009 10:00:17

Нет, это не разрешено, точно так же, как это не разрешено в вопросе, с которым вы связаны (и я не вижу, как «причина отличается»). Это не «ошибка» ни в одном из двух вопросов. Или, по крайней мере, не ошибка в компиляторе. Просто в вашем коде. ;)

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

2
13.10.2009 12:42:03

Самое простое решение для этого:

std::vector<boost::array<LENGTH> > ca_vector;

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

2
13.10.2009 12:46:56
Спасибо за вклад. Фактически в моем конкретном случае vector <string> является (вероятно, предполагаемым) решением проблемы в (унаследованном) исходном коде, который я рассматриваю (так что это не необработанные байты или что-то еще, а просто строки). Я совсем не уверен, почему существует даже массив char [], а не строка, если вектор уже существует; Я могу только представить некоторые неясные (и, вероятно, ошибочные) соображения оптимизации со стороны оригинального автора ...
martin 13.10.2009 12:57:41
Если это строка, используйте строку. Я использовал свою конструкцию как временное решение для хранения байтовых сообщений в stl-контейнере.
stefaanv 13.10.2009 13:14:54
или std :: vector <std :: tr1 :: array <LENGTH>> ca_vector;
matt_h 13.10.2009 16:24:07