2016-04-14 4 views
2

Я начинаю на C++, и я хочу использовать динамическую схему выделения памяти вместо статического (как в массиве) например, я хочу сделать 1D-массив int a [100]; Как я должен делать то же самое с указателем? , что в основном им путать о том, что я просмотрел какой-то учебник по интернету, и они сделали это какНекоторые сомнения в отношении указателей как массивов?

int a[100]; 
int *arr = &a[0]; 

я нашел, что это совершенно бесполезно, потому что сначала мы объявляем массив А размером 100, затем снова мы используем обр указатель я могу это сделать, как этот

int a[1]; 
int *arr= &a[0]; 

теперь, если я делать назначения случайные значения для обр [я] (от г = 0 до I = определяется пользователем) он будет принимать это за I = 1

+0

C++ дает вам много веревки, чтобы повесить себя. –

+0

Вы можете сделать 'int a [1]; a [10] = 5; '. Это может сработать. Или это может упасть. Или это может сработать, но затем может произойти сбой следующего вызова 'printf'. Или это может сработать, но затем вдруг 'printf ("% d \ n ", 1 + 1);' prints 8. – immibis

ответ

1

Это C код вы говорите здесь, и они, как известно, раздражает правильно распределить и размер:

int *arr = malloc(sizeof(int) * 100); 

Это может вернуться NULL, который означает, что вы ничего не получили, так что вы должны проверить, что оно Разработаны. C++ имеет new оператор, по меньшей мере, вызывает исключение, если это не удается, так что делает его труднее игнорировать:

int *arr = new int[100]; 

Вы должны использовать C++ Standard Library контейнеры, такие как std::vector, если вы хотите, чтобы эффективно использовать C++:

std::vector<int> arr(100); 
+0

Спасибо :) последнее, но не менее важное: я могу сделать int * arr = new int [x]; где x == определяется пользователем: D? –

+1

@KeshavSharma Абсолютно, хотя я надеюсь, что вместо этого вы использовали бы контейнер типа 'std :: vector':' std :: vector arr (size) 'где' size' - произвольное значение типа 'size_t' (' unsigned int 'в основном). – tadman

+1

Помните, когда вы выделяете что-то с помощью 'new', вы отвечаете за соответствующий вызов' delete'. Контейнеры хороши тем, что они часто обрабатывают это для вас автоматически. – tadman

3

он будет принимать это за г = 1

Нет, это UB, так как вы пытаетесь получить доступ к памяти вы не выделяло на всех.

Вы можете

int* a = new int[user_define_value]; 
// use it from a[0] ~ a[user_define_value - 1] 
delete[] a; 

BTW: Это хорошая идея, чтобы узнать о std::vector, если вы хотите использовать массив динамического размера, и std::array для статического массива размера в C++.

-1

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

+0

На самом деле это вызывает неопределенное поведение. Вы можете или не можете получить нарушение доступа. –

1

Re фрагмента кода

int a[1]; 
int *arr= &a[0]; 

& hellip; Вы спросите

если я делать назначения случайные значения для обр [я] (от г = 0 до I = определяется пользователем) будет ли он принимать его за пределы = 1

и ответ будет, код будет принят (возможно, с предупреждением), но он будет иметь Неопределенное поведение, UB, поскольку вы будете хранить значения за пределами выделенного массива, который имеет размер 1.

Автоматического расширения необработанного массива нет.


Основной размер массива в динамической C++, является std::vector. Например.

#include <vector> 
using namespace std; 

auto main() -> int 
{ 
    vector<int> a(100); 
    // Your code using it, here. 
} 

& hellip; динамическое распределение буфера. Он также автоматически освобождается в конце. И он может динамически расширяться, например. когда вы используете метод push_back.


С сырых указателей вы можете вместо этого сделать

auto main() -> int 
{ 
    int* a = new int[100]; 
    // Your code using it, here. 
    delete[] a; 
} 

& hellip; но это более хрупкий код, и ему не хватает большой функциональности std::vector, такой как проверка размера, добавления, назначения и общего копирования (особенно для результата функции).

И даже базовая функциональность декларации не полностью эквивалентен, так как с std::vector элементы массива равен нуль инициализированы по умолчанию, в то время как new -expression производит неинициализированных массив, занимающее неопределенных значений , Однако вы можете указать, что вы хотите нулевую инициализацию, добавив пустую скобку. Тогда это выглядит следующим образом:

int* a = new int[100](); 

Это лишь один из многочисленных тонкостей вам приходится иметь дело с тем, когда вы используете сырые указатели и сырые массивы.

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

Вы не можете полностью избежать их (например, main принимает аргумент необработанного массива, любой строковый литерал представляет собой необработанный массив, а API-интерфейсы типа C имеют дело с необработанными массивами), но чем больше вы их избегаете, тем меньше проблем, и тем продуктивнее вы.

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