Как создать массив Dynami c с помощью нового C ++? - PullRequest
0 голосов
/ 03 августа 2020

Я пытаюсь динамически инициализировать массив целых чисел, поскольку размер массива изменяется в зависимости от ввода. Программа выглядит следующим образом:

int main()
{
    int* list = createList("dis.bin");
    for (int i = 0; i < sizeof(list) / sizeof(int); i++)
    {
        printf("%d\n", list[i]);
    }
}

С функцией createList(), как написано:

int* createList(const char* file_name)
{
    int counter = 1;
    int* inst{};
    FILE* myFile = fopen(file_name, "rb");
    if (myFile == nullptr)
    {
        printf("\nFile not opened\n");
        return 0;
    }

    int x = 0;
    for (int i = 0; !(feof(myFile)); i++)
    {
        fread(&x, sizeof(int), 1, myFile);
        inst = new int[counter];
        inst[i] = x;
        printf("%08x #%-4d |   Int equiv: %-12d |   Bin equiv: %s\n", x, counter, inst[i], ToBinary(inst[i], 0));
        counter += 1;
        x = 0;
    }

    return inst;
}

createList читает из файла .bin (в основном содержащего массив байтов) и вставляет каждую пару из 4 байтов в элемент массива inst. Я делаю это, выделяя новый объем пространства для массива на основе переменной counter. (Таким образом, какой бы счетчик значений ни был, он становится размером массива с inst = new int[counter]). Затем я устанавливаю содержимое массива по данному индексу i равным x (считанная пара байтов), я бы предположил, что он работает правильно в createList по крайней мере, из-за оператора printf, который печатает каждый элемент в inst[].

Однако, когда я вызываю createList("dis.bin") в основном и назначаю его переменной int* list, я попробуйте перебрать каждое значение. Но это просто выводит одно неинициализированное значение (-842150451, если вам интересно). Так что я не уверен, что я здесь делаю не так?

Я должен упомянуть, что я НЕ использую векторы или какой-либо контейнер std. Я просто работаю с массивами. Я также использую printf для определенных c причин.

Ответы [ 2 ]

1 голос
/ 03 августа 2020

Этот вопрос помечен как C ++, но OP показывает код C и говорит, что он им нужен в C, поэтому я покажу это в C ... но предварительное требование заключается в том, что он использует new а не malloc

int* createList(const char* file_name, int& count)
{
    // initialize count, so that way if we return early, we don't have invalid information
    count = 0;

    // open the file ad "READ" and "BINARY"
    FILE* myFile = fopen(file_name, "rb");
    if (!myFile)
    {
        printf("\nFile not opened\n");
        return 0;
    }

    // calculate how many 4-byte integers exist in the file using
    // the file length
    fseek(myFile, 0, SEEK_END);
    count = ftell(myFile) / sizeof(int);
    rewind(myFile);
    
    // allocate the memory
    int* returnData = new int[count];

    // read in 4-byte chunks to our array until it can't read anymore
    int i = 0;
    while (fread(&returnData[i++], sizeof(int), 1, myFile) == 1);

    // close the file
    fclose(myFile);

    // return our newly allocated data
    return returnData;
}

int main()
{
    int count;
    int* myInts = createList("c:\\users\\andy\\desktop\\dis.bin", count);
    for (int i = 0; i < count; ++i) {
        printf("%d\n", myInts[i]);
    }
    // don't forget to delete your data. (another reason a vector would be better suited... no one remembers to delete :)
    delete myInts;
}
0 голосов
/ 03 августа 2020

Здесь две вещи:

  1. Использование new было неправильно истолковано мной. По какой-то причине я думал, что каждый раз, когда я выделяю новую память для inst, он просто добавляет новую память к уже выделенной памяти, но это, очевидно, не так. Если бы я хотел смоделировать это, мне пришлось бы копировать содержимое массива после каждой итерации и добавлять его во вновь выделенную память. Чтобы решить эту проблему, я ждал, чтобы выделить память для inst, пока не будет завершена итерация файла.

  2. Как указал Энди, sizeof(list) / sizeof(int) не дал бы мне количество элементов в list, поскольку это указатель. Чтобы обойти это, я создал новый параметр int &read для функции createList(), чтобы передать количество созданных элементов.

С этими точками новая функция выглядит как это и работает по назначению:

int* createList(const char* file_name, int &read)
{
    int counter = 1;
    FILE* myFile = fopen(file_name, "rb");
    if (myFile == nullptr)
    {
        printf("\nFile not opened\n");
        return 0;
    }

    int x = 0;
    for (int i = 0; !(feof(myFile)); i++)
    {
        fread(&x, sizeof(int), 1, myFile);
        printf("%08x #%-4d |   Int equiv: %-12d |   Bin equiv: %s\n", x, counter, x, ToBinary(x, 0));
        counter += 1;
    }

    int* inst = new int[counter];
    read = counter;
    rewind(myFile); // rewind to beginning of file

    for (int i = 0; !(feof(myFile)); i++)
    {
        fread(&x, sizeof(int), 1, myFile);
        inst[i] = x;
        x = 0;
    }
    
    return inst;
}

С основным изменением также немного:

int main()
{
    int read;
    int* list = createList("dis.bin", read);
    for (int i = 0; i < read; i++)
    {
        printf("%d\n", list[i]);
    }
}

Что касается комментариев о недействительности !(feof(myFile)), хотя и полезно, это не было часть моего вопроса и, следовательно, меня не касается. Но я предоставлю решение для этого ради распространения важной информации: Почему «while (! Feof (file))» всегда неверно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...