Как представить INT *, как массив в totalview?
Как мне "нырнуть" int *, который указывает на динамически размещенный массив целых чисел и представляет его как фиксированный массив int[]? Иначе говоря, если я погружаю int *, он показывает адрес и целое число, на которое указывает указатель, но вместо этого я хотел бы видеть массив всех целых чисел.
4 ответа
Я заметил тег TotalView по этому вопросу. Вы спрашиваете, как увидеть значения в вашем массиве в totalview? Если так, то ответ довольно прост.
Допустим, у вас есть указатель p, который имеет тип int *, и он в данный момент указывает на массив с 10 целыми числами.
Шаг 1. Погружение по указателю. Это достигается двойным щелчком, средней кнопкой мыши или использованием опции погружения в контекстном меню - и все это после наведения курсора мыши на переменную в области исходного кода или панели стекового фрейма.
Это откроет новое окно, которое скажет
Выражение: p Адрес: 0xbfaa1234 Тип: int *
и вниз в области данных скажет что-то вроде
0x08059199 -> 0x000001a5 (412)
Это окно показывает вам сам указатель, указанный адрес является адресом указателя. Значение (0x08059199 в приведенном выше примере) является фактическим значением, которое имеет указатель. Все, что находится справа от стрелки, является просто "подсказкой", указывающей, что вы хотите, чтобы она указывала.
Шаг 2. Погрузитесь на указатель снова. Повторите двойной щелчок или среднюю кнопку мыши, на этот раз для значения данных в окне переменной. (Таким образом, вы дважды щелкаете там, где написано 0x08059199).
Это эффективно "разыменовывает" указатель. Теперь окно ориентировано не на сам указатель, а на то, на что указывает указатель. Обратите внимание, что адресное поле теперь содержит 0x08059199, которое было значением ранее.
выражение: *(((int *) p)) Адрес: 0x08059199 Тип: int
и вниз в области данных он скажет что-то вроде
0x000001a5 (412)
Шаг 3. Приведите окно данных к нужному вам типу. Просто щелкните в поле типа и измените его на int[10]. Затем нажмите "вернуться".
Это говорит отладчику, что 0x08059199 является началом массива из 10 целых чисел.
В окне появятся два новых поля: Slice и Filter. Вы можете оставить их в покое, но они могут пригодиться позже.
В области данных теперь будут отображаться два столбца "поле" и "значение" и 10 строк.
Столбец поля будет индексом в массиве [0] - [9], а столбец значения скажет вам, какие данные у вас есть в каждом местоположении массива.
Другие советы:
В более сложных структурах данных вы можете захотеть погрузиться в отдельные элементы (которые также могут быть указателями, дайвинг также будет разыменовывать их)
Вы всегда можете привести к разным типам или длинам, чтобы посмотреть на данные "как если бы"
Вы можете редактировать фактические значения данных, нажав на столбец значений и отредактировав то, что вы там найдете. Это полезно, когда вы хотите спровоцировать конкретное неправильное поведение в вашем приложении
Вы всегда можете отменить операции погружения с помощью значка "<" в верхнем правом углу окна переменной.
Есть несколько онлайн-видео, которые вы можете найти полезными на
http://www.roguewave.com/products/totalview/resources/videos.aspx
в частности, есть один с пометкой "Начало работы с TotalView".
Не стесняйтесь обращаться к нам в Rogue Wave Software за советами по использованию TotalView! поддержка в roguewave dot com - хороший адрес для этого.
Крис Готбрат (Chris dot Gottbrath из roguewave dot com) Менеджер по продукту TotalView в Rogue Wave Software
Вы не можете сделать это осмысленно, не зная точно, сколько целых чисел в массиве.
Это не очень сложно, но я забыл, как это работает. Я нашел вам страницу, которая объясняет это;). Я думаю, что для указания и массива с целыми числами, вызываемыми, например, test, вы должны получить его, используя &test. Просто проверьте эту страницу:
Если у вас есть int *p
который указывает на первый элемент в смежном int
Данные, либо динамически размещенные, либо статический массив, вы можете индексировать его, как если бы это был массив:
int *data = malloc(3 * sizeof *data);
int *p;
/* malloc error detection omitted for brevity */
data[0] = 1;
data[1] = 2;
data[3] = 42;
p = data;
assert(p[0] == 1);
assert(p[1] == 2);
assert(p[2] == 42);
Вы должны знать размер действительных данных, к которым вы обращаетесь таким образом.
Итак, скажем, у меня есть data
как и выше, и хотите написать функцию для печати. Не нужно объявлять функцию следующим образом:
void print_array(int *data);
потому что когда вы звоните print_array(data);
, функция не знает количество элементов для печати.
Вы могли бы определить свой print_array()
лайк:
void print_array(int *data, size_t n);
где n
обозначает количество допустимых элементов, на которые указывает data
, что звонящий должен предоставить. Или вы можете решить, что каждый "массив" будет заканчиваться значением часового, которое используется только в конце данных и не является полезным значением в противном случае:
data[2] = 0; /* data[0] and data[1] are useful, valid values
and data[2] is 0 to signify the end of the data */
Тогда вы можете объявить свой print_array()
как:
void print_array(int *data);
и продолжайте индексировать в data
в определении функции, пока вы не дойдете до стража:
void print_array(int *data)
{
size_t i;
for (i=0; data[i] != 0; ++i)
printf("%d\n", data[i]);
}
Итак, чтобы ответить на ваш вопрос, вы уже можете обращаться с указателем на действительные динамически распределяемые данные как с массивом. Конечно, вы должны помнить размер выделенных данных, что вам также нужно делать в обычном массиве.