Вывод мусора моего int ** в печатной структуре - PullRequest
0 голосов
/ 05 декабря 2018

Я читаю целочисленные значения из файла, анализирую их по пробелу, затем вставляю их в int **, который в моей структуре называется game.Используя операторы print, я подтверждаю, что правильные значения помещаются в int ** в правильную позицию, но как только я выхожу из цикла while или возвращаю структуру, печатаемые значения неверны.

Моя структура:

typedef struct Map_s{

        char * defender;
        char * attacker;
        int missles;
        int ** layout;
        size_t capacity;
        size_t size;
}map;

Инициализация структуры:

map * newGame(){

        map * game = malloc(sizeof(map));
        game->layout = (int**)malloc(_DEFAULT_MAP_SIZE * sizeof(int*));
        game->defender = NULL;
        game->attacker = NULL;
        game->missles = 0;
        game->capacity = _DEFAULT_MAP_SIZE;
        game->size = 0;

        return game;
}

Синтаксический анализ файла:

map * game = newGame();

    char * token;
    char * dup;
    char * ptr;
    int ret;
    const char delim[2] = " ";
    char * buf = NULL;
    char * temp = NULL;
    size_t size = _MAX_SIZE;
    int lineNum = 1;

    while( getline(&temp, &size, fp) > 1 ){
            buf = strtok(temp, "\n");
            dup = strdup(buf);
            if( buf[0] != '#' ){
                    if( lineNum == 1){
                            if( game->defender == NULL ){
                                    game->defender = dup;
                            }
                    }
                    else if( lineNum == 2 ){
                            if( game->attacker == NULL )
                                    game->attacker = dup;
                    }
                    else if( lineNum == 3 ){
                            game->missles = atoi(dup);
                    }
                    else if( lineNum > 3 ){
                            token = strtok(dup, delim);
                            while( token != NULL ){
                                    if( game->size >= game->capacity ){
                                            game->layout = (int**)realloc(game->layout, \
                                                            game->capacity*2 * sizeof(int*));
                                            game->capacity = game->capacity * 2;
                                    }
                                    ret = (int)strtol(token, &ptr, 10);
                                    game->layout[game->size] = &ret;
                                    game->size = game->size + 1;
                                    token = strtok(NULL, delim);
                                    //printf("%s ", token);
                            }
                    }**

                    lineNum++;
            }
    }



    return game;

Я почти уверен, что мой код не работает где-то ввторой цикл пока.Я пытаюсь преобразовать строку в целое число, а затем сохранить ее в правильном месте в int **.

Как я печатаю из main:

for( size_t i = 0; i < thisgame->size; i++ ){
            printf("%d ", *thisgame->layout[i]);
            if( i == 0)
                    continue;
            else if( (i+1) % 10 == 0 )
                    printf("\n");
    }

Вывод из основной функциипосле возврата struct:

0 0 0 0 0 0 0 0 0 0 
10 10 10 10 10 10 10 10 10 10 
10 10 10 10 10 10 10 10 10 10 
10 10 10 10 10 10 10 10 10 10 
10 10 10 10 10 10 10 10 10 10 
10 10 10 10 10 10 10 10 10 10 
10 10 10 10 10 10 10 10 10 10 
10 10 10 10 10 10 10 10 10 10 
10 10 10 10 10 10 10 10 10 10 
10 10 10 10 10 10 10 10 10 10 
10 10 10 10 10 10 10 10 10 10

Как должен выглядеть вывод (что находится в файле):

2 2 2 2 2 2 2 2 2 2
2 2 6 6 7 7 7 5 5 2
2 2 7 7 7 2 2 17 17 17 2
2 2 2 2 2 2 2 2 2 2
8 8 8 6 6 6 9 9 9 2
2 2 2 2 2 2 2 2 2 2
10 10 10 4 4 9 9 9 2
2 2 2 2 2 2 2 2 2 2
3 3 3 6 6 6 9 9 9 2
3 3 3 6 6 6 9 9 9 2
2 2 2 2 2 2 2 2 2 2

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Проблема в том, что вы используете массив int *, когда вы действительно хотите получить массив int .Каждый раз, когда вы сохраняете ret, вы сохраняете один и тот же адрес.Когда вы проверяете значение в цикле, оно будет правильным, потому что ret содержит требуемое значение ... до следующей итерации.

0 голосов
/ 05 декабря 2018

Я вижу пару проблем.

Первая строка **token = strtok(dup, delim);.При первом запуске этой строки token не имеет допустимого значения, и поэтому разыменование его не один, а два раза также вызовет проблемы.Я считаю, что это должно быть просто token = strtok(dup, delim);

Это приведет к первой итерации цикла while в том случае, если блок возвращает неверные значения (все эти 0, по крайней мере, соответствуют этому предположению).

Во-вторых, D Go указал, что вы даете адрес ret (этот адрес не изменяется), так что каждый элемент game->layout имеет одинаковый адрес и, следовательно, смотрит на один и тот же int.(подходит для всех этих 10 с).

Я думаю, что исправлением для этого было бы просто сделать layout массивом int * (подгоняя код распределения под себя) и назначить ret непосредственно каждомуэлемент.

...