Вы выделили пространство для 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: он выглядит как будто ваш код работает правильно, когда на самом деле он ведет себя очень плохо, и может привести к некоторым неприятным проблемам во время выполнения в других местах вашей программы, которые затрудняют отладку.
Вам потребуется явно установить каждый элемент массива 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».