Вы выделили место для 30 указателей, но вы не инициализировали их, чтобы они указывали где-нибудь значимые. Если вы не объявили массив вне функции, каждый элемент в массиве будет содержать некоторую случайную битовую строку, которая может соответствовать или не соответствовать доступной для записи ячейке памяти. Если мы нарисовали картину, это будет выглядеть примерно так (все адреса вытягивают из воздуха, не думайте, что соответствует какой-либо реальной архитектуре):
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
ptr 0xbbc81230 0x?? 0x?? 0x?? 0x??
0xbbc81234 0x?? 0x?? 0x?? 0x??
0xbbc81238 0x?? 0x?? 0x?? 0x??
...
0xbbc812a8 0x?? 0x?? 0x?? 0x??
где 0x??
представляет собой случайное значение байта. Для поведения, которое вы описали, каждое из случайных значений просто происходит, чтобы указать на записываемую память, и записывать все, что там хранится просто происходит, чтобы не иметь непосредственных побочных эффектов.
Bad juju: it выглядит как ваш код работает правильно, когда на самом деле он ведет себя очень плохо, и может привести к некоторым неприятным проблемам времени выполнения в другом месте вашей программы, что является болью для отладки.
Вам нужно будет явно установить каждый элемент массива ptr
, чтобы указать на допустимую ячейку памяти, прежде чем пытаться ее написать.
Предположит, мы добавим следующий код:
ptr[0] = malloc(strlen("foo") + 1);
strcpy(ptr[0], "foo");
ptr[1] = malloc(strlen("bar") + 1);
strcpy(ptr[1], "bar");
Мы динамически выделяемые некоторую дополнительную память для хранения пары строк, и сохраненные указатели на эти новые буфера ptr[0]
и ptr[1]
.
Наша картина будет выглядеть примерно так:
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
0x80ff0000 'f' 'o' 'o' 0x00
...
0x80ffcdc0 'b' 'a' 'r' 0x00
...
ptr 0xbbc81230 0x80 0xff 0x00 0x00
0xbbc81234 0x80 0xff 0xcd 0xc0
0xbbc81238 0x?? 0x?? 0x?? 0x??
...
0xbbc812a8 0x?? 0x?? 0x?? 0x??
ptr[0]
теперь содержит адрес буфера размера, чтобы держать 4 char
значения, и мы копируем строку «Foo» в этот буфер. Аналогично, ptr[1]
содержит адрес другого 4-байтового буфера, который теперь содержит строку «bar».
Также необходимо отметить, что первым элементом в массиве является ptr [0]. – SirDarius
Попробуйте сделать что-то между 'scanf' и 'printf'. Вы должны увидеть какое-то неопределенное поведение. – stanwise
да ptr [0] определенно есть! Спасибо за ваш ответ! –