Динамически размещать массив структур в C - PullRequest
1 голос
/ 23 мая 2011

Я работаю над домашним заданием для CS1, оно должно вернуть нас к скорости, если мы забыли некоторые из наших C (это в основном о указателях и распределении памяти). Я работаю над этим более 15 часов, и мне нужна серьезная помощь.

Проблема говорит нам использовать структуру следующим образом:

typedef struct LottoPlayer {
        char first[20];
        char last[20];
        int nums[6];
} KBLP;

Мы должны прочитать файл и динамически распределить память для массива этих структур, а затем мы можем использовать эту информацию для выбора победителей yada yada. Всякий раз, когда я запускал свой код, я продолжал получать мусор обратно. Так что это то, что у меня есть, я думаю, проблема в арифметике моего указателя или в том, как я настроил свой malloc.

int main() {
    //Code to open the files

    int NumTickets;
    fscanf(infile, "%d", &NumTickets);
    KBLP *size=malloc(NumTickets*sizeof(KBLP));

А потом, когда я читаю файл и записываю его в массив, я делаю

    int index; 
    int i;
    for (index=0; index < NumTickets; index++) { 
        fscanf(infile, "%s", size[index].last);
        fscanf(infile, "%s", size[index].first);
        for (i=0; i<6; i++) {
            fscanf(infile, "%d", size[index].nums[i]);
        }
    }

Теперь я чувствую, что мне здесь не хватает какой-то глупости, потому что, когда я отлаживаю и пытаюсь получить доступ к size [index] .first и тому подобному, я получаю обратно мусорную память. Я не правильно распределяю это? Я правильно не пишу? Или оба?

Ответы [ 3 ]

7 голосов
/ 23 мая 2011

Предполагается, что

fscanf(infile, "%d", &size[index].nums[i]);

Обратите внимание на оператор & во втором аргументе. Конечно, опасения, выраженные в ответе @ missingno, также действительны.

Функции в группе scanf ожидают указателей в качестве аргументов для каждого получателя данных. Вы обязаны применять оператор & всякий раз, когда это необходимо. Компилятор обычно не может проверить, передаете ли вы значение правильного типа, поскольку конечные аргументы этих функций variadic , то есть они не имеют заранее определенного типа. Однако некоторые компиляторы (например, GCC) предпринимают усилия для выполнения проверки, что означает, что ваш код вызовет предупреждение от компилятора GCC для вышеуказанной проблемы.

Обратите внимание, что когда вы передаете аргументы типа массива, тип массива автоматически "распадается" на тип указателя, поэтому первые два fscanf в вашем коде не требуют применения оператора &. Тем не менее, если вы желаете, вы можете переписать эти fscanf s как

fscanf(infile, "%s", &size[index].last[0]);
fscanf(infile, "%s", &size[index].first[0]);
4 голосов
/ 23 мая 2011

первое и последнее заполнение ОК, но вы получаете мусор в числах?

Подсказка: fscanf ("% d" ....) захочет заполнить целочисленное поле. Для этого понадобится указатель. Что вы даете это?

4 голосов
/ 23 мая 2011

На ум приходят две вещи:

  • fscanf(infile, "%d", size[index].nums[i]) отсутствует & до size[.... Вы уверены, что это скомпилировано без предупреждений?

  • fscanf(..., "%s", size[index].last) может перезаписывать данные, если ваша строка содержит более 19 символов (помните, что вам нужен дополнительный символ для терминатора). Напечатайте свои строки, чтобы убедиться, что они имеют правильную длину.

...