|
|
  |
адреса не выделенной памяти |
|
|
|
Jan 15 2015, 13:21
|
Местный
  
Группа: Участник
Сообщений: 295
Регистрация: 2-12-05
Пользователь №: 11 695

|
Цитата(RLC @ Jan 15 2015, 15:43)  решил проблему. дело было в том что я создавал массив размера в зависимости от входных данных и иногда массив становился непомерно большим и в регистре SP появлялись сумашедшие адреса. После фильтрации размера массива всё стало рабочим. Странно одно: инога то в эти сумашедшие адреса не относящиеся к моему RAM всё таки запись был успешна! Как говорится "ежу понятно" (с) Происходил "заворот адресов" на реальный диапазон адресов.
|
|
|
|
|
Jan 16 2015, 11:49
|
Местный
  
Группа: Свой
Сообщений: 271
Регистрация: 6-12-11
Из: Taganrog
Пользователь №: 68 701

|
У Альтеры запись в "мусорные" недопустимые адреса обычно проходит, ничего не вешая. И чтение из них возвращает -1. Хотя лучше бы всё падало при самом первом глюке, без их наслоения. А в С нет понятия "массив переменной длины", автоматические переменные массивов в стеке нужно объявлять на максимально возможную константную длину данных, ну или из кучи выделять динамически, если это значение неизвестно. Очень похоже, что был "заступ" по записи за массив, а в стеке выше локальных переменных и входных параметров вообще много чего интересного сохраняется, в том числе и адреса возвратов из функций, сами значения SP после возврата -- лучше их не трогать, ибо при выходе из функции и восстановлении системных регистров может случиться, что угодно.
|
|
|
|
|
Jan 16 2015, 12:44
|

Участник

Группа: Участник
Сообщений: 60
Регистрация: 19-11-14
Из: СПб
Пользователь №: 83 740

|
Цитата(WitFed @ Jan 16 2015, 14:49)  У Альтеры запись в "мусорные" недопустимые адреса обычно проходит, ничего не вешая. И чтение из них возвращает -1. Хотя лучше бы всё падало при самом первом глюке, без их наслоения. А в С нет понятия "массив переменной длины", автоматические переменные массивов в стеке нужно объявлять на максимально возможную константную длину данных, ну или из кучи выделять динамически, если это значение неизвестно. Очень похоже, что был "заступ" по записи за массив, а в стеке выше локальных переменных и входных параметров вообще много чего интересного сохраняется, в том числе и адреса возвратов из функций, сами значения SP после возврата -- лучше их не трогать, ибо при выходе из функции и восстановлении системных регистров может случиться, что угодно. Ну вот я в отладчике в оочию наблюдал что сохранение в ячейке с адресом 0x55CE FF34 проходит успешно(через Memory Map смотрел), а вот адреное пространств всего лишь от 0x80 0020-0x80 A000. И из этого сумашедшего адреса данные востанавливались успешно! Вот это мне и интересно. а собственно куда сохраняется? Ну а через несколько проходов с такими адресами "вдруг" переставало сохранятся туда. тоесть вроде как команда выполнена, а реально содержимое ячейки как было 0, так и осталось. И с неё содержимое читается как 0 кстати. У меня было так: вход в функцию и в ней объяляется этот массив. Функция универсальная и разумный объём массива будет только в одном из нескольких случаев(собственно он в этом случае и нужен был). В остальных случаях размерность массива больше может получиться чем объём физически доступной памяти(собственно от 0 до 2^32). Сейчас я в нужном случае вызываю ещё одну функцию в котором и создаётся используемый массив объёмом равным аргумента функции. Тоесть массив выделяется статически, но тогда когда известен размер. И вот сейчас я задумался что по факту я каждый раз я создаю, но очистки то не происходит! может мне тогда malloc'ом пользоватья и в конце free делать. Тут же сборки мусора не происходит. Или можно free использовать просто от ссылки на массив который статически выделен. Или функция завершается, ссылку на массив теряется (тк он локальный) и можно забыть про очистку... что то я совсем задумался
|
|
|
|
|
Jan 16 2015, 13:47
|
Местный
  
Группа: Участник
Сообщений: 295
Регистрация: 2-12-05
Пользователь №: 11 695

|
Цитата(RLC @ Jan 16 2015, 15:44)  Ну вот я в отладчике в оочию наблюдал что сохранение в ячейке с адресом 0x55CE FF34 проходит успешно(через Memory Map смотрел), а вот адреное пространств всего лишь от 0x80 0020-0x80 A000. И из этого сумашедшего адреса данные востанавливались успешно! Вот это мне и интересно. а собственно куда сохраняется? Ну а через несколько проходов с такими адресами "вдруг" переставало сохранятся туда. тоесть вроде как команда выполнена, а реально содержимое ячейки как было 0, так и осталось. И с неё содержимое читается как 0 кстати. У меня было так: вход в функцию и в ней объяляется этот массив. Функция универсальная и разумный объём массива будет только в одном из нескольких случаев(собственно он в этом случае и нужен был). В остальных случаях размерность массива больше может получиться чем объём физически доступной памяти(собственно от 0 до 2^32). Сейчас я в нужном случае вызываю ещё одну функцию в котором и создаётся используемый массив объёмом равным аргумента функции. Тоесть массив выделяется статически, но тогда когда известен размер. И вот сейчас я задумался что по факту я каждый раз я создаю, но очистки то не происходит! может мне тогда malloc'ом пользоватья и в конце free делать. Тут же сборки мусора не происходит. Или можно free использовать просто от ссылки на массив который статически выделен. Или функция завершается, ссылку на массив теряется (тк он локальный) и можно забыть про очистку... что то я совсем задумался  Несколько бредово выглядит... "Штудент штоли ???" 1)Кусок С-ишника в студию про "У меня было так: вход в функцию и в ней объяляется этот массив." 2)0x55CE FF34 гдето в 0x80 0020-0x80 A000 и "сохраняется"
|
|
|
|
|
Jan 16 2015, 15:56
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Да чувствуется некое непонимание%) Цитата я каждый раз я создаю, но очистки то не происходит! и сразу решение Цитата может мне тогда malloc'ом пользоватья и в конце free делать Опускаем вопросы создания массивов, того что такое стэк и куча. Сосредоточимся на решении проблемы "каждый раз создаю, но очистки то не происходит", почему это вас ведет не к решению сделать массив 1 раз и использовать его чтобы стэк не тилипать, а к наоборот более сложному изнасилованию кучи через доп функции  ?
|
|
|
|
|
Jan 20 2015, 07:45
|

Участник

Группа: Участник
Сообщений: 60
Регистрация: 19-11-14
Из: СПб
Пользователь №: 83 740

|
1) Код writeBytes(alt_u8 array[], alt_u32 address,alt_u8 id, alt_u32 data){ alt_u8 tempArray[data],//тот самый статически выделенный массив(сейчас создаётся в tempArray). иногда data это размер в последствии пришедших данных а иногда это просто любое число(вот тогда и возникали непонятные адреса) ... switch(id){ case(...): break; case(...): break; case(0x35): writeBlockData(array,data)//тут теперь процедура в которой создаётся массив c длинной дата break; }
} 2) Код .... alt_u8 *memory=0; memory=address; for(index=0;index<(data+2);index++){ *(memory+index)=IORD_DIRECT(....); ... } если честно то сейчас уже интересно только куда сохранялись данные по адресам которые я не выделял. В какое физическое место. т.к ситуация решена. ну а с созданием массива я тупил, согласен. Ссылка на вершину масива теряется поле входа из функции. Где тут вымучивание кучи? Глобальные массивы не люблю. вообще глобальные не люблю. хотя тут наверное оптимально было бы. Но опять же я только минимальный массив создать смогу, а при приходе точного необходимого размера мне придётся вызывать каждый раз malloc. Либо создавать сразу гиганский массив на всю доступную мне память.
Причина редактирования: слеш не в ту сторону стоял (с) модератор
|
|
|
|
|
Jan 20 2015, 08:47
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
MMU - MPU на вас нету. сохраняются данные туда же куда и при int[10] Data; Data[11] = 10;
то есть в память с адресом &Data[0] + 11*4, а что там лежит одному вам известно. Так можно спокойно загадить данные, другие переменные, даже если очень постараться можно код программы завалить.
Дальше больше если выбрать ячейку вне пределов вашей памяти, она свернеться и попадет куда-то в адрес который у вас есть.
Вообще это базовые понятия программирования, винды тут нет которая напишет приложение выполнила недопустимую ошибку и будет закрыто, или как она там писала?
Локальные массивы выделяются на стеке, стек кончиться начнут гадить оперативку. Глобальные массивы выделены сразу в оперативке, менять их размеры на лету не выйдет. Массивы динамические создаются на куче, со всеми делами по организации, дефрагментации и прочей байде с кучей. Потому вместо одноразового массива выделяемого на стеке придумать одноразовый массив в куче - это мучение кучи, созданием и удалением массивов, ее фрагментации и так далее...
хорошим тоном в вашем случае является проверка data на допустимые значения
а вторым хорошим тоном является создавать массив всегда одной величины с запасиком, и проверкой влезет ли дата в него или нет. А то так далеко можно уйти, в непредсказуемые дали...
|
|
|
|
|
Jan 22 2015, 11:39
|

Участник

Группа: Участник
Сообщений: 60
Регистрация: 19-11-14
Из: СПб
Пользователь №: 83 740

|
Golikov A., спасибо за объяснение. Когда я пишу по конкретным адресам, то конкретные адреса в ходят в разряд памяти не являющейся RAM для NIOS. Тоесть это память в которую я пишу и заю что она незаорется программой. от такая особенность. ну вот странно у меня адресов таких больших нет в Qsys проекте. вот максимальные как раз 0x80 a000. Вся переферия меньшие адреса имеет. Всем спасибо за внимание
|
|
|
|
|
Jan 22 2015, 14:42
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
ПИПЕЦ!!!!! просото пипец!!!
вы что нибудь про шины адреса знаете? если у вас шина 2 бита и программа занимает адреса 0, 1, 2, 3
то запись в адрес 4, 5, 6, 7 - это запись в 3 битную шину 4 = 100 5 = 101 6 = 110 7 = 111 , а теперь представьте что это 3 бита выставлдяются на 2 битной шине, что будет, откинеться старший бит и что убдет? 100 = 00 101 = 01 110 = 10 111 = 11 понято что стало? 0 1 2 3
когда у вас что-то за пределами РАМ для ниос, это что-то ограничено разрядностью шины адреса, и запись туда, это запись в младшие адреса.
Нельзя так делать, нельзя писать туда, куда надеетесь программа не дотянется! Для этого есть линкеры, можно выделить область памяти, регион, запретить линкеру туда лезть, и использовать для своих нужд, зная что там точно не будет программы, но только так! никак иначе...
Можно взять большой массив выделить 1000 элементов, и по указателю обращаться в него как в память, и знать что это не загадиться, а так как вы решили эту проблемму - это ПИПЕЦ!!!!
|
|
|
|
|
Jan 22 2015, 18:09
|
Местный
  
Группа: Участник
Сообщений: 295
Регистрация: 2-12-05
Пользователь №: 11 695

|
Цитата(Golikov A. @ Jan 22 2015, 17:42)  ПИПЕЦ!!!!! просото пипец!!!
вы что нибудь про шины адреса знаете? если у вас шина 2 бита и программа занимает адреса 0, 1, 2, 3
то запись в адрес 4, 5, 6, 7 - это запись в 3 битную шину 4 = 100 5 = 101 6 = 110 7 = 111 , а теперь представьте что это 3 бита выставлдяются на 2 битной шине, что будет, откинеться старший бит и что убдет? 100 = 00 101 = 01 110 = 10 111 = 11 понято что стало? 0 1 2 3
когда у вас что-то за пределами РАМ для ниос, это что-то ограничено разрядностью шины адреса, и запись туда, это запись в младшие адреса.
Нельзя так делать, нельзя писать туда, куда надеетесь программа не дотянется! Для этого есть линкеры, можно выделить область памяти, регион, запретить линкеру туда лезть, и использовать для своих нужд, зная что там точно не будет программы, но только так! никак иначе...
Можно взять большой массив выделить 1000 элементов, и по указателю обращаться в него как в память, и знать что это не загадиться, а так как вы решили эту проблемму - это ПИПЕЦ!!!! Спасибо за красочное описание... меня не хватило на это в 6 сообщении...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|