Почему отладчик показывает только один элемент из моего указателя массива? - PullRequest
2 голосов
/ 12 марта 2012

Прежде всего: я знаю, что new - это способ C ++ сделать это. Я просто показываю, что есть несколько способов воспроизвести эту ошибку, и оба невероятно расстраивают.

У меня есть две формы этого исходного файла. Я пытаюсь отладить еще одно задание на программирование, но я не прошу помощи по этому вопросу. По сути, я пытаюсь повторно реализовать set как класс с полями для размера и указателем на массив int. Вот код, использующий new:

testnew.cpp

int main()
{
    int size = 1;
    int *elements = new int[size];
    elements[0] = 0;
    size++;
    int * temp = new int[size];
    for (int i = 0; i < (size - 1); i++)
    {
        temp[i] = elements[i];
    }
    delete[] elements;
    temp[size] = size;
    elements = temp;
    elements[1] = 1;
    delete[] elements;
}

и снова, используя менее предпочтительные alloc функции:

testalloc.cpp

int main()
{
    int size = 1;
    int * elements = (int *) malloc(sizeof(int) * size);
    elements[0] = 0;
    size++;
    elements =(int *) realloc(elements,size * sizeof(int));
    elements[1] = 1;
    free(elements);
}

В обоих случаях моя цель - создать массив, а затем добавить к нему. Однако в обоих случаях, после сборки и запуска в Visual Studio 2010, массив вообще не увеличивается и имеет только 1 «слот» для моих элементов, чтобы войти в . В отладчике VS я наблюдаю за указателем массива elements; прикреплен скриншот. Он одинаков для обеих версий кода.

My watches at the end of the program

- точка останова при вызове delete[] / free().

Серьезно, что я делаю не так? Это должно быть логической ошибкой, и я пролистал четверть дюжины примеров malloc / realloc и new, прочитал и перечитал мой учебник, и я не вижу, в чем дело!

Мне кажется, что у меня должна быть строка, которая разбивает выделенную память на массив, но разве вызов new int[] не делает этого?

Ответы [ 5 ]

5 голосов
/ 12 марта 2012

Помимо любых других проблем с кодом, вы должны либо сделать то, что Джо Готерин упомянул, и иметь несколько часов, либо установить часы следующим образом:

elements,5

приведет к:

enter image description here

Я не знаю, есть ли обновленный список для VS2010, но это все еще работает: Символы для переменных часов
А также: Просмотр массива в отладчике Visual Studio?

4 голосов
/ 12 марта 2012

В других ответах указана ошибка в вашем коде (temp[size] = size;), однако ваша путаница связана с тем, что вы неправильно читаете вывод отладчика.

Что касается системы типов и отладчика, elements это не массив, это указатель. Отладчик не может узнать, является ли это указателем на первый элемент в массиве или указателем на один элемент.

Если вы хотите увидеть значение elements[x] в своем отладчике, используйте выражение *(elements+x).

2 голосов
/ 12 марта 2012

В первом примере это неверно:

temp[size] = size;

Это будет означать:

temp[2] = 2;

И поскольку массивы имеют нулевую индексацию, вы пишете за пределами выделенной области.

1 голос
/ 12 марта 2012

Прежде всего C ++ проиндексирован на 0, поэтому temp[size] = size; отключено на одну ошибку. И чтобы ответить на ваш вопрос, тип элементов - int*. То, что это на самом деле массив - это не знание, которое доступно VS без анализа кода. Итак, вам нужно либо использовать, например, std :: vector <>, boost :: array, либо убедиться, что ваш массив никогда не искажается до int*.

1 голос
/ 12 марта 2012

Файл testnew.cpp выделяет память для size элементов в temp, но затем устанавливает temp[size], который является элементом size+1. Возможно, это должно быть

temp[i] = size;

Файл testalloc.cpp фиксирует общую ошибку переназначения памяти для одной и той же переменной без проверки того, что вызов realloc завершился успешно:

elements =(int *) realloc(elements,size * sizeof(int));

Если realloc завершится неудачно, для elements будет установлено значение null, а его исходная память будет потеряна.

...