Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/48: Рейтинг темы: голосов - 48, средняя оценка - 4.71
0 / 0 / 0
Регистрация: 29.11.2013
Сообщений: 2
1

segmentation fault(

29.11.2013, 17:14. Показов 8722. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
int i,n,str[n];
str[n]=(int)malloc(200);
srand(time(NULL));
n=rand()%9;
for(i=0;i<n;i++) {
str[i]=rand()%9;
}
scanf("%d",&str[i]);
return 0;
}

Chto ne tak? Pomogite...
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.11.2013, 17:14
Ответы с готовыми решениями:

Segmentation fault
Собственно отрывок кода: my_news.max_news = atoi(sql(&quot;SELECT COUNT(*) FROM t_news WHERE a_id&quot;));...

Segmentation fault strcpy()
Почему я получаю ошибку сегментации? char* m_buf; m_buf = (char*)malloc(sizeof(buf)/sizeof(char)...

Segmentation fault(Core dumped)
#include &lt;math.h&gt; #include &lt;stdio.h&gt; #include &lt;iostream&gt; using namespace std; int main() {...

Bad allocation || Segmentation fault
Люди, помогите плиз!! голова уже взрывается, но как найти ошибку, не могу понять!! Не могу привести...

18
8 / 6 / 5
Регистрация: 11.11.2013
Сообщений: 75
29.11.2013, 18:30 2
Анечка, удивительно, что у вас этот код вообще скомпилировался. Вы ж пытаетесь создать дивный гибрид статического и динамического массива. Суть в том, что размер для статического массива не задается динамически, а динамический массив не задается так, как вы его задали.

Мало того. Вы с чистой совестью даете компьютеру команду выделить а хрен его знает сколько памяти. В строке с malloc'ом значение n еще не задано.

Начните с этого. И вообще, лучше словами объясните, что должна делать программа. А то ваш код, кажется, не отражает всю глубину ваших замыслов
0
0 / 0 / 0
Регистрация: 29.11.2013
Сообщений: 2
29.11.2013, 18:38  [ТС] 3
программа должна создать массив с рэндомным количеством чисел, выбранных тоже рэндомно) и вывести его на экран. каким то образом код скомпилировался, НО при выполнении ./ выдаёт segmentation fault.
0
8 / 6 / 5
Регистрация: 11.11.2013
Сообщений: 75
29.11.2013, 19:34 4
Я не могу сказать, почему конкретно выдавался сегментейшн фолт. У меня этот код предсказуемо не скомпилировался.

Должно быть как-то так:
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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int main() {
  int i, n, timer;
  long ltimer;
  int *arr = new int[n]; //правильно создаем динамический массив
  
  ltimer = time (NULL);  //получаем текущее время
  timer = (unsigned int) ltimer/2; //многовато будет, незачем так грузиться
  srand(timer); //инициализация генератора
  arr = (int *)malloc(10); // правильно выделяем память под массив
  if (arr != NULL) {   //... и если выделили ее успешно, то
    n = rand()%9;      //получаем случайное число
    for (i=0; i<=n; i++) {   //заполняем массив n случайными числами
      arr[i] = rand()%9;
    }
    printf("Массив: %d %s", arr, "\n"); //...выводим массив на экран
  }
  else printf("Хьюстон, у нас проблемы."); //если не получилось выделить память, то выводим сообщение
  free (arr);  //и в любом случае освобождаем выделенную память,
               //чтоб с детства не привыкать делать ошибки
  return 0;
}
Добавлено через 13 минут
P.S. Пардон, в вашем коде в malloc я не увидела, что там число, а не n передается. Если у вас действительно такой пофигистичный компилятор, то ошибка памяти могла возникнуть при попытке передать ссылку на выделенную память в статистический массив неизвестного размера.
1
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
29.11.2013, 21:56 5
Цитата Сообщение от Ullaluna Посмотреть сообщение
Если у вас действительно такой пофигистичный компилятор, то ошибка памяти могла возникнуть при попытке передать ссылку на выделенную память в статистический массив неизвестного размера.
Ошибка возникла именно по этой причине.
А компилятор не обижайте. Cогласно стандарту (включая C99) он ДОЛЖЕН компилировать указанный код, несмотря на его абсурд, выдав соответствующие предупреждения. (об использовании неинициализированной переменной gcc сообщает при наличии опции -Wall)
0
8 / 6 / 5
Регистрация: 11.11.2013
Сообщений: 75
29.11.2013, 22:35 6
У меня именно gcc 4.7 не хотел компилить указанный код, ругаясь на строку:
C++
1
str[n]=(int)malloc(200);
таким образом:
error: cast from ‘void*’ to ‘int’ loses precision [-fpermissive]
0
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
29.11.2013, 23:22 7
Bash
1
2
3
4
5
6
7
8
9
10
11
gg@c-1:~/cc/tmp$ gcc tmp.c 
tmp.c: In function ‘main’:
tmp.c:10:8: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
 
gg@c-1:~/cc/tmp$ g++ tmp.c 
tmp.c: In function ‘int main()’:
tmp.c:10:23: error: cast from ‘void*’ to ‘int’ loses precision [-fpermissive]
 
gg@c-1:~/cc/tmp$ g++ -fpermissive tmp.c 
tmp.c: In function ‘int main()’:
tmp.c:10:23: warning: cast from ‘void*’ to ‘int’ loses precision [-fpermissive]
Добавлено через 19 минут
PS.
C
1
str[n]=(long)malloc(200);
должен пройти без замечаний на архитектуре, где указатели вмещаются в long.
0
8 / 6 / 5
Регистрация: 11.11.2013
Сообщений: 75
30.11.2013, 00:59 8
Прошло без замечаний только после замены строки на Вашу. Выдал сегментейшн фолт. Цель достигнута!

Если модератор не сочтет за флейм, то интересно спросить: что происходит здесь на уровне памяти?

1) создается статический массив случайной длины

2) указатель, возвращаемый функцией маллок, записывается в этот массив (в конец массива) в виде long. На 64-х битной системе в этот момент побеждают зло и хаос, о чем и гласит название темы.

3) Если будет 32-х битная система, то с большой степенью вероятности все прокатит. Последний элемент массива, куда записался адрес памяти, будет перезаписан в цикле, так что пользователь даже не заметит. Ночью моск не варит, но как-то так получается.

Я тоже недолго программирую, мне это интересно. Да и автору темы полезно будет.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.11.2013, 02:26 9
Цитата Сообщение от Ullaluna Посмотреть сообщение
Если у вас действительно такой пофигистичный компилятор, то ошибка памяти могла возникнуть при попытке передать ссылку на выделенную память в статистический массив неизвестного размера.
Цитата Сообщение от gng Посмотреть сообщение
Ошибка возникла именно по этой причине.
На моей системе ошибка возникает хоть и на этой строке, но еще до вызова malloc. По причине ошибки доступа к стеку, думаю, для того, чтобы положить в него адрес возврата. А указатель стека указывает на память, в которой нет доступа из-за переполнения стека.
Попробуйте из этой строки удалить "str[n]=(int)" и оставить только malloc, может свалиться на нем же, если повезет с данными на стеке.

Добавлено через 5 минут
Цитата Сообщение от Ullaluna Посмотреть сообщение
указатель, возвращаемый функцией маллок
malloc может и не вызваться.
И эта ошибка будет воспроизводиться не всегда. Если увеличить размер стека каким-нибудь ulimit -s, то ее можно избежать и приложение не будет падать.
0
8 / 6 / 5
Регистрация: 11.11.2013
Сообщений: 75
30.11.2013, 03:01 10
На Suse 12.3 падает даже при закомментированной строке с маллоком. НЕ падает, если задать размер статического массива при объявлении:
C++
1
int i,n,str[10];
или присвоить значение n до создания массива:
int i,n=10,str[n];
Господа, почему так? То есть, все по учебнику, конечно. Но если копать до причин - то почему? В первоначальном варианте переменная n имела некое случайное значение. В моем случае это 0, сколько ни перекомпилируй. Но как-бэ я читала, что в случайной области памяти это может быть что угодно из анамнеза компьютера.

И ладно, пускай ноль! Ведь массив нулевой размерности тоже можно было объявить:

#
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
int i,n;
int str[0];
//malloc(200);
srand(time(NULL));
n=rand()%20;
for(i=0;i<n;i++) {
str[i]=rand()%9;
}
printf("%d",&str[i]);
 
return 0;
}
Этот код компилируется и работает.

Если все дело в n, почему так важно, что размерность не объявлена черным по белому? В чем (с точки зрения процессора) разница между случайной областью памяти, которую компилятор автоматически переведет в число, и "осмысленно" присвоенным значением?
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.11.2013, 03:05 11
Цитата Сообщение от Ullaluna Посмотреть сообщение
На Suse 12.3 падает даже при закомментированной строке с маллоком.
Логично. Я не говорил о том, что он не упадет. Я пишу о том, что причина не в str[n] =
Цитата Сообщение от Ullaluna Посмотреть сообщение
НЕ падает, если задать размер статического массива при объявлении:
Тоже логично )
Цитата Сообщение от Ullaluna Посмотреть сообщение
Но если копать до причин - то почему?
С чего ты взяла, что 0? Запусти valgrind на свое приложение, покажи вывод.
Цитата Сообщение от Ullaluna Посмотреть сообщение
Если все дело в n, почему так важно, что размерность не объявлена черным по белому?
Переполнение стека, выше писал.
Цитата Сообщение от Ullaluna Посмотреть сообщение
В чем (с точки зрения процессора) разница между случайной областью памяти, которую компилятор автоматически переведет в число, и "осмысленно" присвоенным значением?
В том, что у разных областей памяти разные права доступа. Почитай про стек и про то, как он работает.
0
8 / 6 / 5
Регистрация: 11.11.2013
Сообщений: 75
30.11.2013, 03:06 12
C++
1
И эта ошибка будет воспроизводиться не всегда.
У меня всегда.

C++
1
Если увеличить размер стека каким-нибудь ulimit -s, то ее можно избежать и приложение не будет падать.
Дайте свой вариант кода, давайте проверим?)

От чего зависит разница в реакции различных linux ОС на один и тот же код? Не первый раз встречаю, что сегментейшн фолт постоянно выдается на одной системе, и далеко не каждый раз - на другой.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.11.2013, 03:17 13
Цитата Сообщение от Ullaluna Посмотреть сообщение
У меня всегда.
какая разница, что у тебя... Я говорю, что воспроизводиться она будет не всегда. А ты пишешь, что у тебя..
Это зависит не от твоей ОС.

Добавлено через 3 минуты
Цитата Сообщение от Ullaluna Посмотреть сообщение
Дайте свой вариант кода, давайте проверим?)
Пожалуйста:
C
1
2
3
4
5
6
7
8
9
10
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
        int i,n,str[n];
        str[n]=(int)malloc(200);
        for(i=0;i<n;i++) ;
        return 0;
}
> ./a.out
Segmentation fault
> ulimit -s 64000
> ./a.out
>
Добавлено через 55 секунд
Цитата Сообщение от Ullaluna Посмотреть сообщение
От чего зависит разница в реакции различных linux ОС на один и тот же код?
От ОС это не зависит. От компилятора, от того, какой мусор окажется на стеке, от размера стека.
0
8 / 6 / 5
Регистрация: 11.11.2013
Сообщений: 75
30.11.2013, 03:22 14
В том, что у разных областей памяти разные права доступа.
Вот!(с)
Разве это разные области памяти? Это одна и та же переменная n, как я понимаю. В одном случае там наше значение, в другом - мусор, из которого компилятор сделает значение. Заметьте, я не утверждаю, что я права.)

Переполнение стека, выше писал.
Я не успеваю отвечать. Да, похоже. Сколько массив максимум может занять памяти?

Добавлено через 2 минуты
[QUOTE=Vourhey;5412821]/QUOTE]
Узбагойся.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.11.2013, 03:37 15
Цитата Сообщение от Ullaluna Посмотреть сообщение
Вот!(с)
что такое?
Цитата Сообщение от Ullaluna Посмотреть сообщение
Разве это разные области памяти?
Смотря, что ты понимаешь под "область памяти". Разные страницы с разным доступом.
Цитата Сообщение от Ullaluna Посмотреть сообщение
Это одна и та же переменная n, как я понимаю.
А при чем тут переменная n?
Цитата Сообщение от Ullaluna Посмотреть сообщение
В одном случае там наше значение, в другом - мусор, из которого компилятор сделает значение. Заметьте, я не утверждаю, что я права.)
ладно, блин, на пальцах... Возьмем, например, что стек у программы 1 мегабайт. Опустим, что стек растет от больших адресов к меньшим. Для простоты пусть будет наоборот. И вот у нас стек лежит по адресам от 0 до 1024. Когда я говорю, что объявляю массив str[10], то он, грубо, валяется в области от 0 до 9. Когда ты вызываешь функцию на стек кидаются еще всякие данные (опустим пока конкретику). То есть, в область, начиная с 10 (адрес после массива) запишутся какие-то данные.
Но если у меня берется случайное значение, то массив может занять область от 0 до 16000, например. Получается, что адрес 16000 уже выходит за пределы памяти выделенной для стека. И у нашей программы доступа туда уже может не оказаться (как повезет). И вызов функции еще до своего начала упадет при ошибке доступа к 16001 адресу.
Так понятнее?

Добавлено через 5 минут
Цитата Сообщение от Ullaluna Посмотреть сообщение
Сколько массив максимум может занять памяти?
Автоматический? Зависит от того, сколько система выделит памяти стеку
Протестируй:
C
1
2
3
4
5
6
7
8
9
10
11
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
        char s[1600000];
        int i, n;
        malloc(200);
        for(i=0;i<n;i++) ;
        return 0;
}
Сделай ulimit -s 1024 в одном шелле и запусти. Открой шелл по умолчанию и запусти то же приложение без перекомпиляции. Вот тебе без n в размерности массива.
1
8 / 6 / 5
Регистрация: 11.11.2013
Сообщений: 75
30.11.2013, 03:37 16
что такое?
Ну как же, цитата великих и не очень людей. "Вот!" говорят, слегка вытаращив глаза, с поднятым вверх указательным пальцем, когда собеседник (или сам говорящий) внезапно понял, о чем весь разговор.

Так понятнее?
Да, майнхерц, в целом это именно то, что мне надо. И спасибо тебе огромное за объяснение. А есть какая-нибудь хорошая литература по теме? Я по образованию не программист никаким макаром, для меня такие вещи не само собой разумеется.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.11.2013, 03:41 17
Цитата Сообщение от Ullaluna Посмотреть сообщение
внезапно понял
В данном случае, надеюсь, говорящий?

Добавлено через 1 минуту
Цитата Сообщение от Ullaluna Посмотреть сообщение
А есть какая-нибудь хорошая литература по теме?
Например:
http://www.ozon.ru/context/detail/id/5061928/
http://www.ozon.ru/context/detail/id/2631566/
И книги по отладке могут содержать в себе по частям разную информацию, обычно там это описывается.
0
8 / 6 / 5
Регистрация: 11.11.2013
Сообщений: 75
30.11.2013, 03:57 18
Прекрасные книги, спасибо.
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
07.12.2013, 00:49 19
Цитата Сообщение от Ullaluna Посмотреть сообщение
2) указатель, возвращаемый функцией маллок, записывается в этот массив (в конец массива) в виде long.
не в конец, а за конец

Цитата Сообщение от Ullaluna Посмотреть сообщение
3) Если будет 32-х битная система, то с большой степенью вероятности все прокатит. Последний элемент массива, куда записался адрес памяти, будет перезаписан в цикле, так что пользователь даже не заметит.
в цикле тот "элемент" даже затронут не будет, потому что цикл работает в пределах массива

чтобы понять, нужно сначала это дело разравнять (сделать читаемым)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
int main() {
    int i, n, str[n];
    
    str[n] = (int) malloc(200);
    
    srand(time(NULL));
    n = rand() % 9;
 
    for (i = 0; i < n; i++) {
        str[i] = rand() % 9;
    }
    
    scanf("%d", &str[i]);
    return 0;
}
итого: 9-ая и 18-ая строки - запись за край массива
0
07.12.2013, 00:49
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.12.2013, 00:49
Помогаю со студенческими работами здесь

Исправить ошибку, приводящую к segmentation fault
Всеем привет! Можете подсказать, как убрать эту ошибку: Program received signal SIGSEGV,...

Segmentation fault в конце работы программы
Есть массив: std::string names; Если в него заносится любое кол-во строк (до 1010), у которых до...

XDestroyImage(image); Segmentation fault (core dumped)
Здравствуйте, подскажите пожалуйста как быть. при вызове функции XDestroyImage(image); происходит...

При записи в бинарный файл происходит segmentation fault
Всем доброго времени суток. В узлах дерева находятся структуры pair. #include &lt;stdio.h&gt; #include...

Segmentation fault (core dumped) при большом размере массива
При большом размере массива (при перекомпиляции размера массива при котором вылезает ошибка...

Printhepl ключом -h выдает что делает программа, но в конце пишет segmentation fault(core damped)
Помогите выявить ошибку, компилю в линуксе, когда вызывают Printhepl ключом -h он выдает что делает...


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

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru