C/C++

Откуда мусор в массиве? (Си)

Откудав этом массиве берётся мусор после буквы "h"?

int main() {
char arr []={'h'};
printf("%c\n", arr[1]);
return 0;
}
Буква h в бинарном коде имеет вид: 01101000
8 бит - 1 Байт, как раз такое же место выделяется под один символ.
Про добавление нуля после символа я в знаю. И про то что если массив инициализировать, то тоже мусора не будет. Интересно почему мусор в данном виде кода появляется.
Lok-Диман -Dok
Lok-Диман -Dok
288
int main() {
char arr []= { 'h' } ;
printf("%c\n", arr[0]); // <-- ноль как индекс
return 0;
}

Вы просто выходите за пределы массива. Что там за массивом - кто знает. Отсюда и "мусор".
Murat Abdukadyrov
Murat Abdukadyrov
84 764
Лучший ответ
Lok-Диман -Dok Это чтоб мусора не видеть? h является нулевым символом массива, но я специально ввёл 1 чтоб показать мусор присутствующий в массиве.
Lok-Диман -Dok Структуры я ещё не учил.

Я вышел за пределы массива в соседнюю область с массивом значит.
Оператор %s тоже выходит уа пределы массива? Потому что мусор так же показывает.
int main() {
char arr []={'h'};
printf("%s\n", arr);
return 0;
}
Lok-Диман -Dok Да, про терминатора я читал. Интересно откуда мусор без терминатора.
Lok-Диман -Dok Мусор при выходе за пределы массива понятно откуда. Хотя в массиве нет индексов, почему это вышли за пределы массива.
В массиве нет индексов и теперь на месте любого элемента массива будет мусор.
Lok-Диман -Dok int arr[]={ 'h' };
Мне кажется что этот массив состоит из h и бесконечного числа элементов на месте которых мусор. Возможно есть ограничения конечно под массивы и это число не бесконечно)
Lok-Диман -Dok Вот этот массив ограничен 5тью символами char arr[4])={'h'};
Lok-Диман -Dok Этот массив потенциально расширяем char arr[]= { 'h' } ;
В нём индексов.
printf("%s\n", arr[100]); разве вышли за пределы массива? не думаю. просто в этом элементе массива будет мусор.
Потому что arr[100] не инициализировал.
Так же например как проверить в printf не инициализированную переменную.
Lok-Диман -Dok char arr []= { 'h' } ;
arr[1]='G'
Расширил. Расширяем.
А вот так не получится.
char arr [1]= { 'h' } ;
arr[1]='G'
Lok-Диман -Dok Получается почему то. хмм
Lok-Диман -Dok Ага. Предупреждение в компиляторе говорит что индекс 1 находится за концом массива.
Lok-Диман -Dok Вы про этот вариант писали что записал в область памяти не относящуюся к массиву?
char arr []= { 'h' } ;
arr[1]='G'
Такой вариант я много где видел. Разве так не делают?
Lok-Диман -Dok В тыртырнете читал что это допустимый вариант объявления, инициализации массива.
Lok-Диман -Dok Пытаюсь разобраться, но как сказал я структуры ещё не изучал.
Lok-Диман -Dok Давным давно Яваскрипт учил, да. Но забыл всё уже.
Lok-Диман -Dok Ок, это когда выходим за пределы существующего массива.
Мапример: char arr[1]={'h'}; arr[1]='G';
Но в вашем примеренет объявления пустого массива.
Или это то же самое?
char arr[]={'h'};
Не раз видел такой вариант в уроках. А после этого именно добавление в массив чго либо.
arr[1]='G';
Могу даже ссылку на видео найти. Много в инете.
Lok-Диман -Dok Я вам верю))
Пустой массив я имел в виду это char arr[]= { 'h' } ;
Без индексов в квадратных скобках.
Lok-Диман -Dok https://youtu.be/Zpml91CY8jY?t=637
Например здесь. Можно ещё поискать
Lok-Диман -Dok Понятно. Допустимо изменение только в уже существующих границах. Существующие границы заданы при инициализавии.
char arr[]={'h'}; Здесь 1 элемент и дальше чем 1 изменять не имеем права иначе выйдем за границы массива.
Lok-Диман -Dok Есть значит нужные? А я догадывался.
Lok-Диман -Dok Если указать любую цифру в квадратных скобках char arr[1] при объявлении массива, то команда printf выдаст 0 на любой неициализированный элемент массива.
Если в этом случае я вышел за пределы массива, хотите сказать что всё пространство после массива превратилось в нули?
int main() {
char arr[1]={'h'};
printf("%d\n", arr[500]);
return 0;
}
Размер вашего массива равен одному элементу типа char. Вы попытались обратится ко второму элементу в массиве и совершили выход за его пределы. В таком случае поведение программы не определено. То есть она может получить доступ к случайным данным по указанному адресу и интерпретировать их в соответствие с указанным типом либо получить отказ в доступе и в этом случае программа во время отладки сообщит об ошибке времени выполнения, связанной с повреждением памяти, а во время её выполнения преждевременно закроется по той же причине.

P.S. Размер вашего массива можно определить следующим образом:

printf("Size: %i\n", sizeof(arr) / sizeof(arr[0]));
Lok-Диман -Dok Количество бит разделили на количество элементов массива.
Я это смотрел без деления. 1 бит= 1 символ)
Lok-Диман -Dok А если много элементов в массиве, наверное нужно делать цикл, складывать все данные и потом делить? Было бы логично.
Сейчас то просто 1/1=1
Lok-Диман -Dok Хотя, таким действием получаем количество бит в одном элементе.
Lok-Диман -Dok *в одном элементе массива
Lok-Диман -Dok Я помню в интернете смотрел.
Там используется что то типа такого sizeof(arr)/sizeof(char)
Нужно знать размер в битах одого символа и разделить на него общее количество бит в массиве. Получаем количество. элементов массива.
Lok-Диман -Dok А, ок. Первый элемент (как и любой другой элемент массива) это ведь то же самое что и тип одного элемента массива.
Но "kh fjkg" тоже мусор, а не нормальное имя +_-
Lok-Диман -Dok Это абстракционизм)
допиши еще строчку между char arr []= { 'h' } ;
printf("%c\n", arr[1]);

unset($myArr[?]);

В том случае, если ничего не известно о ключе конкретного элемента массива, а есть данные только об его значение, в такой ситуации придется осуществлять процесс перебора всех элементов и искать тот, который необходим. К примеру, при необходимости удаления элемента массива со значением (2), код программы будет выглядеть таким образом:

$myArr = array(1,2,3,4,5);
foreach($myArr as $key => $item){
if ($item == 2){
unset($myArr[$key]);
}
}
Lok-Диман -Dok Какую строчку дописать? Зачем? sizeof() можно дописать чтоб убедиться что на символ выделяется 1 Байт.