Печать динамического массива в C - PullRequest
0 голосов
/ 29 апреля 2011

Я пишу программу на C. Я использую динамический массив в своей программе и использую цикл for для циклического перемещения по элементам в массиве. Проблема, с которой я столкнулся, заключается в том, что когда я иду на печать списка на экран (в цикле for), все предыдущие элементы в списке заменяются на последний созданный элемент. Я не знаю, что вызывает это. Я много раз просматривал код в GDB и до сих пор не могу найти, что не так.

/* For Loop, Displays Weapon List */
for (i = 1; i < num_places; i++)
{
    printf("%d. \n",i);
    printf("Des: %s \n\n",weap_List[i].description);
}

/* Add function, adds a weapon to the list */
int Add_weap(weapon new_weap) 
{
    if (num_places == num_allocated) 
    {
        if (num_allocated == 0)
                num_allocated = 3;
        else 
            num_allocated *= 2;
        void *_tmp = realloc(weap_List, (num_allocated * sizeof(weapon)));
        weap_List = (weapon*)_tmp;
    }
    num_places++;
    weap_List[num_places] = new_weap;
    return num_places;
}

/* Code that invokes the function, adding the weapon to the list */
printf("Adding new weapon \n");
weapon temp;
printf("Please enter the description of this new weapon. \n");
scanf("%s",weap.description);
Add_weap(temp);

/* Weapon structure */
typedef struct {
    char* description;
} weapon;

Если бы вы могли указать мне правильное направление, это было бы очень ценно.

Ответы [ 2 ]

2 голосов
/ 29 апреля 2011

Вы увеличиваете num_places в неправильное время.

Изменение

  num_places++;
  weap_List[num_places] = new_weap;

до

  weap_List[num_places++] = new_weap;
1 голос
/ 29 апреля 2011

Несколько быстрых мыслей:

for (i = 1; i < num_places; i++)
{

num_places, будучи индексом массива, начнется с 0.Этот цикл плохо провалится, если в вашем списке только ноль или одно оружие.(Условие i < num_places проверяется после первой итерации тела цикла. Если weap_List имеет один элемент (с индексом 0), этот цикл будет обращаться к памяти, котораяне распределяется и не печатать оружие. Запустить циклы обработки массивов с 0. Единственный раз, когда вы должны когда-либо допускать одноиндексные массивы, это когда вы перемещаете огромное количество кода FORTRAN в C; при запускес нуля, используйте массивы с нулевым индексом, как и предполагал K & R.:)

   void *_tmp = realloc(weap_List, (num_allocated * sizeof(weapon)));
   weap_List = (weapon*)_tmp;

Если бы _tmp было объявлено (weapon *) tmp = realloc(...), тогда вам не понадобился бы (weapon *)бросьте на следующей строке.

Крошечный придира: удвоение размера - довольно дорогой способ добавления 196609-го оружия.Рассмотрим только рост на восемь каждый раз.(По вашим именам я предполагаю, что вы, вероятно, не собираетесь добавлять один элемент в секунду в течение нескольких недель подряд.)

Крошечный придира: избегайте _prefix имен переменных, они зарезервированы для Cсреда выполнения.Да, почти каждая программа использует их, и да, Я использовал их, и да, это, вероятно, безопасно :), но они технически защищены.Достаточно простого tmp.

Больший придир: вы не проверяете возвращаемое значение из realloc(3).Это может потерпеть неудачу.Ваше приложение должно обрабатывать сбои как можно более изящно.

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