2010-10-23 3 views
1

Можно создать дубликат:
What's the difference between new char[10] and new char(10)то, что отличается от char * t = new char и char * t = new char [10];

, что отличается от

char* t1=new char 

и

char* t2=new char[10]; 

как выделить память и t1 [100] = 'т' и t2 [100] = 'т' является правильным для них

----------- после редактирования:

но почему мы можем используйте t1 [100], если t1 динамически назначен char, а не массив char

+0

Что вы подразумеваете под "t (x) [100] = 'm" подходит для них? " Это просто совпадение, что вы можете установить эту память на «m» без сбоя вашей программы. Вы не выделили эту память, так что вы записываете конец массива в память, что может быть чем угодно. –

+1

В основном дубликат: http://stackoverflow.com/questions/3902011/whats-the-difference-between-new-char10-and-new-char10, за исключением последнего комментария в вашем вопросе. 't [100] = 'm'' хорошо сформирован, но приводит к неопределенному поведению для обоих случаев. Не. – GManNickG

+1

Вы можете использовать 't1 [100]', потому что, когда 'X' является указателем' X [I] ', эквивалентно' * (X + I) '. Вы просто слепо перемещаете значение указателя на 100 элементов и разыгрываете. C++ не заботит и не пытается защитить программиста от глупостей. Тебе решать. – GManNickG

ответ

0

t1 указывает на динамически выделенный символ; t2 указывает на динамически выделенный массив из 10 символов. Но я считаю, что это C++, а не C. И это, безусловно, дубликат.

Редакция после редактирования параметров порядка р [п], где р является указателем и п представляет собой целое число эквивалентно * (р + п), следовательно, это как доступ к 100 символов от того, что ваши р указывает. В обоих случаях (t1 и t2) 100-й (101-й) элемент находится вне вашей собственности, поэтому это UB. Фактически вышеупомянутый факт делает законным писать 2[array] взаимозаменяемо с array[2]. Необычные, но не делают этого :)

3

Вы должны delete эти по-разному, так как массивы выделяются с использованием другого варианта operator new:

delete t1; 
delete [] t2; 
4

Ваш первый случай создает один char элемент (1 байт) тогда как ваш второй случай создает 10 последовательных элементов char (10 байтов). Тем не менее, ваш доступ t(x)[100]='m' в обоих случаях не определен. То есть вы запрашиваете 100 байт после позиции указателя, который, скорее всего, является мусором.

Другими словами, ваше назначение «m» перезапишет все, что уже есть, что может быть данными из другого массива. Таким образом, во время выполнения вы можете столкнуться с некоторыми причудливыми ошибками.

C/C++ позволяет программистам получать доступ к массивам за пределами границ, потому что массив действительно является указателем на последовательную память. Соглашение t1[100] составляет всего 100 байт после указателя, независимо от того, что это такое.

Если вы хотите «безопасные» массивы, используйте класс vector и вызовите функцию at(). Это приведет к исключению out_of_range, если доступ недействителен.

Stroustrup приводит следующий пример:

template<class T> class Vec : public vector<T> { 
public: 
    Vec() : vector<T>() {} 
    Vec(int s) : vector<T>(s) {} 

    T& operator[] (int i) {return at(i);} 
    const T& operator[] (int i) const {return at(i);} 
}; 

Этот класс является границей безопасным.Я могу использовать его вот так:

Vec<char> t3(10);    // vector of 10 char elements 
try { 
    char t = t3[100];   // access something we shouldn't 
} 
catch (out_of_range) { 
    cerr << "Error!" << endl; // now we can't shoot ourselves in the foot 
}