Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
bgm123
40 / 40 / 27
Регистрация: 29.01.2013
Сообщений: 277
#1

Перераспределение памяти, realloc

14.04.2013, 12:34. Просмотров 1210. Ответов 11
Метки нет (Все метки)

Есть код, который считывает из файла слова и записывает их в динамическую записную книжку. Всё работает сначала нормально. Ошибка возникает при перераспределение памяти. Раннее считанные строки не перераспределяются, а теряются. Вот вопросы:
1)Как перераспределить память для двойного указателя?
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
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define INITIAL_SIZE_BOOK 5
#define SIZE_BUF 1024
 
#define ERR_OPEN_FILE 1
#define ERR_MEMORY 2
 
int main(int argc, char *argv[])
{
    char **book;
    long flag, id, max_id = INITIAL_SIZE_BOOK - 1;
    char buf[SIZE_BUF], pathToFile[SIZE_BUF];
    FILE *fp;
    int i;
    
    printf("enter path to file: ");
    scanf("%s", pathToFile);
    if( !(fp = fopen(pathToFile, "rt")))
        exit(ERR_OPEN_FILE);
 
    book = (char **)calloc(INITIAL_SIZE_BOOK, sizeof(char *));
    if(!book) exit(ERR_MEMORY);
    
    id = 0;
    flag = fscanf(fp, "%s", buf);
    while(!feof(fp) && flag > 0)
    {
        book[id] = (char *)malloc(strlen(buf) * sizeof(char));
        strcpy(book[id], buf);
        id++;
 
        if(id == max_id){
            max_id *= 2;
            book = (char **)realloc(book, max_id);
        }
 
        flag = fscanf(fp, "%s", buf);
    }
 
    fclose(fp);
    
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.04.2013, 12:34
Ответы с готовыми решениями:

Перераспределение памяти
Здравствуйте. Если писать такой код #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; ...

Перераспределение памяти в отдельной функции
Добрый день! Имею некое недопонимание с указателями/адресами в C/C++. ...

Перевыделение памяти realloc
Есть двумерный массив char **inpWords, в который я добавляю слова из файла,...

Ошибка при перераспределении памяти realloc
Здравствуйте, дорогие друзья. Помогите, пожалуйста разобраться с...

Выделение памяти с помощью функции realloc
в общем задачка по сути своей вроде бы легкая, должна укладываться в 60...

11
easybudda
Модератор
Эксперт CЭксперт С++
10054 / 5974 / 1493
Регистрация: 25.07.2009
Сообщений: 11,320
14.04.2013, 13:56 #2
bgm123, во-первых под строку нужно выделять на один символ памяти больше (32 строка), а во-вторых в 38
C
1
book = (char **)realloc(book, max_id * sizeof(char*));
и снова либо выделять на указатель больше, либо сначала значение id на равность max_id проверять, а уж за тем память для book[id] выделять.
больше вроде ничего не увидел, разве что нужно проверять результаты функций распределения памяти и ввода/вывода, тем более, файлового.
0
bgm123
40 / 40 / 27
Регистрация: 29.01.2013
Сообщений: 277
14.04.2013, 14:21  [ТС] #3
Вот немного изменил код, ошибка осталась. Описание ошибки: сначала слова из файла читаются корректно. Но потом, когда в книге больше нет места, я вызываю функцию realloс для двойного указателя book, где book - это массив указателей. На сколько я понимаю, все мои одномерные указатели book[i] должны при этом переместиться в новую область памяти, выделенную для book. Но почему-то некоторые указатели сбиваются????


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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define INITIAL_SIZE_BOOK 3
#define SIZE_BUF 1024
 
#define ERR_OPEN_FILE 1
#define ERR_MEMORY 2
 
int main(int argc, char *argv[])
{
    char **book;
    long flag, id, max_id = INITIAL_SIZE_BOOK;
    char buf[SIZE_BUF], pathToFile[SIZE_BUF];
    FILE *fp;
    int i;
    
   // printf("enter path to file: ");
    //scanf("%s", pathToFile);
    if( !(fp = fopen("in.txt", "rt")))
        exit(ERR_OPEN_FILE);
 
    book = (char **)calloc(INITIAL_SIZE_BOOK, sizeof(char *));
    if(!book) exit(ERR_MEMORY);
    
    id = 0;
    flag = fscanf(fp, "%s", buf);
    while(!feof(fp) && flag > 0)
    {
        if(id == max_id){
            max_id *= 2;
            book = (char **)realloc(book, max_id);
        }
 
        book[id] = (char *)malloc((strlen(buf) + 1) * sizeof(char));
        strcpy(book[id], buf);
        id++;
 
        
 
        flag = fscanf(fp, "%s", buf);
    }
 
    fclose(fp);
 
    for(i = 0; i <= id; i++)
        printf("%s\n", book[i]);
    
    return 0;
}
Добавлено через 1 минуту
вы могли вы в студии посмотреть в чём здесь может быть дело?
0
easybudda
Модератор
Эксперт CЭксперт С++
10054 / 5974 / 1493
Регистрация: 25.07.2009
Сообщений: 11,320
14.04.2013, 14:37 #4
bgm123, посмотрите на 34 строку у себя и на ту, что я написал, найдите одно, но очень важное отличие...
1
bgm123
40 / 40 / 27
Регистрация: 29.01.2013
Сообщений: 277
14.04.2013, 14:46  [ТС] #5
Всё заработало. Спасибо.
0
easybudda
Модератор
Эксперт CЭксперт С++
10054 / 5974 / 1493
Регистрация: 25.07.2009
Сообщений: 11,320
14.04.2013, 15:01 #6
bgm123, да не за что, только ещё одно замечание: увеличивать размер массива лучше не в два раза, а на тот же INITIAL_SIZE_BOOK, иначе получается геометрическая прогрессия, и доступная память при достаточно большом файле закончится раньше, чем могла бы. Опять же результат работы realloc у Вас не проверяется...
0
bgm123
40 / 40 / 27
Регистрация: 29.01.2013
Сообщений: 277
14.04.2013, 15:01  [ТС] #7
Только теперь новая ошибка, связанная с нарушением прав доступа. Не пойму почему. Если можете гляньте.
Вот код:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define INITIAL_SIZE_BOOK 5
#define SIZE_BUF 1024
 
#define ERR_OPEN_FILE 1
#define ERR_MEMORY 2
 
int main(int argc, char *argv[])
{
    char **book;
    long flag, id, max_id = INITIAL_SIZE_BOOK;
    char buf[SIZE_BUF], pathToFile[SIZE_BUF];
    FILE *fp;
    int i;
    
    printf("enter path to file: ");
    scanf("%s", pathToFile);
    if( !(fp = fopen(pathToFile, "rt")))
        exit(ERR_OPEN_FILE);
 
    book = (char **)calloc(INITIAL_SIZE_BOOK, sizeof(char *));
    if(!book) exit(ERR_MEMORY);
    
    id = 0;
    flag = fscanf(fp, "%s", buf);
    while(!feof(fp) && flag > 0)
    {
        if(id == max_id){
            max_id *= 2;
            book = (char **)realloc(book, max_id * sizeof(char *));
        }
 
        book[id] = (char *)malloc((strlen(buf) + 1) * sizeof(char));
        strcpy(book[id], buf);
        id++;
    
        flag = fscanf(fp, "%s", buf);
    }
    if(flag > 0) 
        strcpy(book[id], buf);  //вот здесь почему-то появляется ошибка
 
    fclose(fp);
    
    for(i = 0; i <= id; i++)
        printf("%s\n", book[i]);
 
 
    return 0;
}
Вот входной файл:
0
Миниатюры
Перераспределение памяти, realloc  
bgm123
40 / 40 / 27
Регистрация: 29.01.2013
Сообщений: 277
14.04.2013, 15:02  [ТС] #8
Ошибка отмечена в строке 45, мат где комментарии.
0
easybudda
Модератор
Эксперт CЭксперт С++
10054 / 5974 / 1493
Регистрация: 25.07.2009
Сообщений: 11,320
14.04.2013, 15:07 #9
bgm123, ну а память-то под последнюю строку Билл Гейтс выделять будет?
да и весь цикл чтения лучше сделать
C
1
2
3
while ( fscanf(fp, "%s", buf) == 1 ) {
    /*...*/
}
1
bgm123
40 / 40 / 27
Регистрация: 29.01.2013
Сообщений: 277
14.04.2013, 15:34  [ТС] #10
Вот учёл всё ваши замечание и исправил код, также добавил освобождение памяти.
Можете глянуть у меня нет нигде утечек памяти и вообще правильно ли выполняется работа с памятью?


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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define INITIAL_SIZE_BOOK 5  
#define SIZE_BUF 1024        
 
#define ERR_OPEN_FILE 1
#define ERR_MEMORY 2
 
int main(void)
{
    char **book;
    long i, id, max_id = INITIAL_SIZE_BOOK;
    char buf[SIZE_BUF];
    FILE *fp;
        
    printf("enter path to file: ");
    scanf("%s", buf);
    if( !(fp = fopen(buf, "rt")))
        exit(ERR_OPEN_FILE);
 
    //выделяем память для блокнота
    book = (char **)calloc(INITIAL_SIZE_BOOK, sizeof(char *));
    if(!book) exit(ERR_MEMORY);
    
    //записываем слова в блокнот из файла
    id = 0;
    while(fscanf(fp, "%s", buf) == 1)
    {        
        if(id == max_id){
            max_id += max_id;
            book = (char **)realloc(book, max_id * sizeof(char *));
            if(!book) exit(ERR_MEMORY);
        }
 
        book[id] = (char *)malloc((strlen(buf) + 1) * sizeof(char));
        strcpy(book[id], buf);
        id++;
    }
    
    fclose(fp);
    
    puts("book:");
    for(i = 0; i < id; i++)
        printf(" %s\n", book[i]);
    
    for(i = 0; i < id; i++)
        free(book[i]);
    free(book);
     
    return 0;
}
0
easybudda
Модератор
Эксперт CЭксперт С++
10054 / 5974 / 1493
Регистрация: 25.07.2009
Сообщений: 11,320
14.04.2013, 16:43 #11
bgm123, а чем принципиально max_id += max_id оличается от max_id *= 2 ? Ну и при выделении памяти под строку тоже неплохо проверять, что она выделилась. А так вроде правильно. Работает?
0
bgm123
40 / 40 / 27
Регистрация: 29.01.2013
Сообщений: 277
14.04.2013, 16:54  [ТС] #12
Да, работает
0
14.04.2013, 16:54
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.04.2013, 16:54

Realloc
Программа должна забивать массив command_comblock символами 'p', но она...

Использование realloc
Доброго времени суток. Определен динамический массив, он вводится. Затем нужно...

Realloc в функции
Есть функция void read_line(char *adress) { char temp = '1'; ...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru