Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.86/14: Рейтинг темы: голосов - 14, средняя оценка - 4.86
1080 / 1007 / 107
Регистрация: 28.02.2010
Сообщений: 2,889

Ошибка сегментации при выходе за пределы динамического массива

23.12.2012, 08:56. Показов 3464. Ответов 28
Метки нет (Все метки)

Всем привет.
Вопрос: что нужно сделать (если это возможно), чтобы ВСЕГДА при выходе за пределы динамического массива была ошибка сегментации?

Данный вопрос у меня возник на следующем примере (по идее должен выводить одну и туже матрицу 2 раза):
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include <stdlib.h>
 
void printm(double* m, int n)
{
    int i, j;
    
    for (i=0; i<n; i++)
    {
        for (j=0; j<n; j++)
        {
            printf("m[%d]=%f\t", i*n+j, m[i*n+j]);
        }
        printf("\n");
    }
    printf("-----------\n");
}
int main(int argc, char* argv[])
{
    int n = 3, i;
    double* left = (double*)malloc(n*sizeof(double));
    double* right = (double*)malloc(n*sizeof(double));
    
    for (i=0; i<n*n; i++)
    {
        left[i] = i;
        right[i] = i;
        printf("right[%d]=%f\n", i, right[i]);
    }
    
    printm(right, n);
 
    
    return 0;
    
}
Вывод у меня был таким:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
eugene@pc-eugene:~/c/valab3$ gcc test1.c -Wall
eugene@pc-eugene:~/c/valab3$ ./a.out
right[0]=0.000000
right[1]=1.000000
right[2]=2.000000
right[3]=3.000000
right[4]=4.000000
right[5]=5.000000
right[6]=6.000000
right[7]=7.000000
right[8]=8.000000
m[0]=4.000000   m[1]=5.000000   m[2]=6.000000   
m[3]=7.000000   m[4]=8.000000   m[5]=5.000000   
m[6]=6.000000   m[7]=7.000000   m[8]=8.000000   
-----------
Вывод вызвал у меня в недоумение из-за того, что я выделил n элементов вместо n*n.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.12.2012, 08:56
Ответы с готовыми решениями:

Ошибка о выходе за пределы массива
При изменении условия s&gt;1 на s&gt;0 ошибка о выходе за пределы массива. как исправить? #include &lt;iostream&gt; #include &lt;vector&gt;...

Почему работает программа при выходе за пределы массива?
Добрый день, возникла проблема. Я задал одномерный массив из 10 элементов, однако, когда в я цикле пытаюсь присвоить значения большему...

"Неопределенное поведение" при выходе вводимых данных за пределы массива
В условии задачи написано, что функция не проверяет индексы. И если введенные пользователем входные данные будут выходить за пределы...

28
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
07.01.2013, 11:07
Psilon, я Вас опять (так же как с malloc(0)) не понимаю. Какая связь между electric-fence(сторонние средство поиска ошибок, которому без разницы как именно адресуется память, любой выход за _верхнюю_ границу оно успешно ловит) и тем что Вы тут написали?
0
Master of Orion
Эксперт .NET
 Аватар для Psilon
6102 / 4958 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
07.01.2013, 18:45
"C" славится быстротой, а это обеспечивается отсутствием всевозможных проверок, GC и прочего высокоуровневого хлама. Если их добавлять, то С начинает превращаться в калечного и угробищного клона С#
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
07.01.2013, 20:23
Цитата Сообщение от Psilon Посмотреть сообщение
"C" славится быстротой, а это обеспечивается отсутствием всевозможных проверок, GC и прочего высокоуровневого хлама. Если их добавлять, то С начинает превращаться в калечного и угробищного клона С#
Эк Вас прёт, только раздел не тот... шли бы Вы в https://www.cyberforum.ru/holywars/
0
3 / 3 / 1
Регистрация: 04.02.2011
Сообщений: 37
08.01.2013, 11:41
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
У efence в этом плане есть существенный недостаток - не умеет ловить такое:
Код C
1
2
char *a = malloc(1234);
a[-1] = N; /* Выход за нижнюю границу. */
Наверняка у нее есть исходный код и его можно переписать бгг. Можно даже профилирование включить, чтобы посмотреть сколько аллокаций возникает. Потому это не такое уж значительное замечание.

Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
electric-fence(сторонние средство поиска ошибок
Это не средство, а библиотека переопределяющая вызов malloc и все. Думаю разница есть.

Цитата Сообщение от Psilon Посмотреть сообщение
"C" славится быстротой, а это обеспечивается отсутствием всевозможных проверок, GC и прочего высокоуровневого хлама. Если их добавлять, то С начинает превращаться в калечного и угробищного клона С#
Можно зделать в make-файле разделы debug (в котором определено все что нужно для отладки) и release (где все соответсвенно для конечной версии). Таким образом хлам будет только на стадии отладки. Да и проверки нужны для логики программы.
1
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
08.01.2013, 12:52
Цитата Сообщение от crastin Посмотреть сообщение
Наверняка у нее есть исходный код и его можно переписать бгг. Можно даже профилирование включить, чтобы посмотреть сколько аллокаций возникает. Потому это не такое уж значительное замечание.
Что Вы собрались переписывать??? Прелесть решения в его простоте:
Памяти выделяется всегда на 1 страницу больше, на эту "лишнюю" страницу ставиться защита на запись/чтение, возвращается указатель на адрес конца 1й страницы минус остаток от разницы размера блока в байтах и размера блока в страницах умноженный на размер одной страницы. Картинко для malloc(1) без учета настроек выравнивания:
[страница 1 разрешены чтение и запись][страница 2 чтение и запись запрещенны]
[xxx...xxx размер=4095 байт, 1 байт, указатель на который нам вернут]
Т.к. защитить часть страницы не возможно, доступ к любому из обозначенных как "x" байт _не_ ловиться.
Нужно _совершенно_ иное решение.
Цитата Сообщение от crastin Посмотреть сообщение
Это не средство, а библиотека переопределяющая вызов malloc и все.
Как угодно назовите, что измениться?
Цитата Сообщение от crastin Посмотреть сообщение
Думаю разница есть.
Если Вы о моем
которому без разницы как именно адресуется память
то поясните, в чем эта разница...
1
3 / 3 / 1
Регистрация: 04.02.2011
Сообщений: 37
08.01.2013, 14:30
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Что Вы собрались переписывать??? Прелесть решения в его простоте:
Памяти выделяется всегда на 1 страницу больше, на эту "лишнюю" страницу ставиться защита на запись/чтение, возвращается указатель на адрес конца 1й страницы минус остаток от разницы размера блока в байтах и размера блока в страницах умноженный на размер одной страницы. Картинко для malloc(1) без учета настроек выравнивания:
[страница 1 разрешены чтение и запись][страница 2 чтение и запись запрещенны]
[xxx...xxx размер=4095 байт, 1 байт, указатель на который нам вернут]
Т.к. защитить часть страницы не возможно, доступ к любому из обозначенных как "x" байт _не_ ловиться.
Нужно _совершенно_ иное решение.
Признаюсь. Я только начал читать исходник и ранее не задумывался о функционале. Функция memalign выравнивает выделяемую память по верхнему диапазону, что не позволяет обращаться к памяти дальше границы. Но это не протеворечит тому что есть возможность привести efence к такому виду
[страница 1 чтение и запись запрещенны][страница 2 разрешены чтение и запись]
но это нужно для редкого и малоупотребляемого варианта и выход за верхний диапазон перестанет работать.

Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Если Вы о моем
которому без разницы как именно адресуется память
то поясните, в чем эта разница...
Нет не о этом, а о разнице между переопределением реализации и стороннем средстве.

Добавлено через 2 минуты
Кстати, на моей машине efence выделяет 4кб на один, т.е. это в 2 раза меньше чем должно быть.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
08.01.2013, 15:00
Цитата Сообщение от crastin Посмотреть сообщение
[страница 1 чтение и запись запрещенны][страница 2 разрешены чтение и запись]
но это нужно для редкого и малоупотребляемого варианта и выход за верхний диапазон перестанет работать.
Конечно можно, более того если я верно помню у efence для этого есть флаг, но хочется то одновременно...
Цитата Сообщение от crastin Посмотреть сообщение
Кстати, на моей машине efence выделяет 4кб на один, т.е. это в 2 раза меньше чем должно быть.
Вы как то не так смотрите... на первый malloc() вообще будет минимум три страницы.
0
3 / 3 / 1
Регистрация: 04.02.2011
Сообщений: 37
08.01.2013, 16:34
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Вы как то не так смотрите... на первый malloc() вообще будет минимум три страницы.
Вот код, выделяет 42Мб на 10240 вызовов malloc

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
 
#define ONE_K (1024)
 
int main() {
    char *some_memory;
    int  size_to_allocate = ONE_K;
    int  megs_obtained = 0;
    int  ks_obtained = 0;
 
    int i = 0;
    while (i < 10) {
        for (ks_obtained = 0; ks_obtained < 1024; ks_obtained++) {
            some_memory = (char *)malloc(size_to_allocate);
            if (some_memory == NULL) exit(EXIT_FAILURE);
            sprintf(some_memory, "Hello World");
        }
        megs_obtained++;
        printf("Now allocated %d Megabytes\n", megs_obtained);
    i++;
    }
   
    while(1) {sleep(10);}
 
 
    exit(EXIT_SUCCESS);
}
P.S.: Удалил из системы efence, вместо этого скомпилировал существующую с флагом pg. Теперь аллокации профилируются.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
08.01.2013, 19:05
Цитата Сообщение от crastin Посмотреть сообщение
Вот код, выделяет 42Мб на 10240 вызовов malloc
А что этот пример должен показать то?
Я конечно смотрел efance довольно давно, и в принципе что-то могло поменяться...
было как-то так: на старте выделяется мегабайт (может больше, не помню уже) под будущие вызовы malloc(), при отработке malloc() ищется свободная/создается набор структур служебных блоков размером 1 страницу (это раз), ищется свободная память подходящего размера с учетом страницы под защиту(это уже минимум 2 страницы), и собственно ставиться защита на последнюю страницу найденного куска (это третья).
Если так интересно глянуть как оно работает, то логично взять и посмотреть Помнится там всего то 2 маленьких файла кода и капелька заголовков.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.01.2013, 19:05

Прокрутка в canvas при выходе содержимого за пределы
Доброго временни суток. Возникло несколько проблем: Есть Canvas на форме. Предполагается динамически добавлять на него другие...

Изменение выравнивания при выходе текста за пределы контейнера
Добрый день! Подскажите, пожалуйста, как можно реализовать следующую конструкцию: Текст находится в блоке, выравнивание по центру. При...

Алгоритм движения ракеты при выходе за пределы Земли
Дана скорость ракеты при выходе за пределы атмосферы Земли. Составить алгоритм определения того, как будет двигаться ракета после...

Алгоритм движения ракеты при выходе за пределы Земли
Здравствуйте! Дана скорость ракеты при выходе за пределы атмосферы Земли. Составить алгоритм определения того, как будет двигаться ракета...

Выход за пределы динамического массива
#include &lt;iostream&gt; using namespace std; int main() { int** mas = new int*; for(int i=0; i &lt; 20; i++) mas = new...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
29
Ответ Создать тему
Новые блоги и статьи
23. что сделано за последнее время.
anaschu 17.06.2026
• Эталон: Клиника НИИ питания РАМН, Москва — централизованный пищеблок, 225 коек, 180 пациентов • Git: репозиторий med2, ветка абсентеизм. Рабочий файл: СРесурсами1_v4. alp • Смежный проект:. . .
22. Подключение слоя системной динамики (потоковые диффуры): экономические метрики модели
anaschu 17.06.2026
Апдейт модели: финансовый контур, разделение затрат Продолжаю развивать модель рабочего коллектива на AnyLogic. В этот раз работа шла над агентом Экономика — финансовым SD-слоем модели. Задача:. . .
[golang] Insert Delete GetRandom O(1) (Leetcode: 380)
alhaos 16.06.2026
Insert Delete GetRandom O(1) Сложность: Medium Источник: LeetCode 380 Задача Реализовать структуру данных RandomizedSet, которая поддерживает следующие операции за O(1) в среднем:
Свет в конце тоннеля
kumehtar 16.06.2026
Поймал себя на одной мысли. Раньше мне всегда казалось неправильным жить без чёткого понимания, куда всё идёт. Будто я иду по дороге судьбы, но не знаю, куда она ведёт. А раз не знаю — значит,. . .
[golang] Реализация стека с поддержкой получения минимального элемента за O(1)
alhaos 16.06.2026
Min Stack Сложность: Medium Источник: LeetCode 155 Задача: Реализовать стек который поддерживает push, pop, top и получение минимального элемента за O(1). Методы:
[golang] Конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов.
alhaos 10.06.2026
Задача Реализовать конкурентный fetcher с ограничением максимального количества одновременных HTTP запросов. Сигнатура func Fetch(urls string, maxConcurrent int) Result Пример urls :=. . .
[golang] Состояние гонки (race condition)
alhaos 10.06.2026
Состояние гонки (race condition) Состояние гонки (Race Condition) — это ошибка, возникающая при одновременном доступе нескольких горутин к одним и тем же данным без должной синхронизации. При этом. . .
Взрослые отношения, и почему они не получаются
kumehtar 09.06.2026
Когда в детстве ребёнок не получает от родителей чего-то важного, он лишается не просто приятных переживаний, а основы для формирования определённых внутренних качеств и навыков. Если ребёнок не. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru