2015-04-14 2 views
0

Для этих структурных определений я инициализирую их все, а затем распечатаю их содержимое с помощью printstruct(); но после печати первого элемента программа неожиданно зависает,

1. Я думал, что если malloc() не удалось, это будет для всех элементов правильно ?.
2.I, к сожалению, приходится работать с этими структурами, любые идеи не в порядке с кодом ниже?

Примечание: Все символьные массивы имеют размеры, равные максимальной длиной содержания они получат плюс один для нулевого завершающего символа «\ 0», каждая команда имеет максимум 7 игроков, количество команд 21000.
Извините за этот вопрос проверки ошибок, но я никогда не работал с структурами на C++ в прошлом.Печать массива структур structs приводит к непредвиденной ошибке выполнения?

typedef struct Player{ 
char firstName[50]; 
char lastName[50]; 
}Player; 

typedef struct Team{ 
    int id; 
    char title[50]; 
    char summary[100]; 
    int numberOfPlayers; 
    Player *players; 
}Team; 

typedef struct TeamsLog{ 
    Team *arr; 
    int numberOfTeams; 
}Teams; 

int main() 
{ 
    TeamsLog log; 
    log.numberOfTeams = 21000; 
    log.arr = (Team*)malloc(log.numberOfTeams * sizeof(Team)); 

    for (int i = 0; i < log.numberOfTeams; ++i) 
    { 
     (log.arr+ i)->id = 1; 
     (log.arr + i)->numberOfPlayers = 7; 
     for (int l = 0; l < 10; ++l) 
     { 
      (log.arr + i)->summary[l] = '0' + l; 
      (log.arr + i)->title[l] = '0' + l; 
     } 
     (log.arr + i)->summary[10] = '\0'; 
     (log.arr + i)->title[10] = '\0'; 
     log.arr->players = (Player*)malloc(7 * sizeof(Player*)); 
     for (int l = 0; l < 7; ++l) 
     { 
      for (int k = 0; k < 10; ++k){ 
       (log.arr + i)->players[l].firstName[k] = '0' + k; 
       (log.arr + i)->players[l].lastName[k] = '0' + k; 
      } 
      (log.arr + i)->players[l].firstName[10] = '\0'; 
      (log.arr + i)->players[l].lastName[10] = '\0'; 
     } 
     printstruct(log.arr + i); 
    } 


} 

Код printstruct():

void printstruct(Team* arg) 
{ 
    cout << "\nTeam Name: " << arg->title 
     << "\nId: " << arg->id 
     << "\nSummary: " << arg->summary 
     << "\nNumber of players: " << arg->numberOfPlayers << endl; 
    for (int j = 0; j < arg->numberOfPlayers; ++j) 
     cout << "Player " << j+1 << " " << ((arg->players) + j)->firstName << " " 
      << ((arg->players) + j)->lastName << endl; 
} 
+0

«Все символьные массивы имеют размеры, равные максимальной длиной содержания они будут получать» ... + 1 для завершающего '\ 0' ? –

+0

@Paul Roub Включая '\ 0' Я отредактирую благодарность за указание – hitter

+6

'sizeof (Player *)' должен быть 'sizeof (Player)'. И используйте 'std :: string' и' std :: vector' insead этой ошибки, подверженной ошибкам, жонглируя указателем (или переключитесь на C, если вам нравится такая вещь). –

ответ

1

Когда я копировать/вставить свой код, который я получил Segfault из-за следующего:

log.arr->players = (Player*)malloc(7 * sizeof(Player*)); 

Вы забыли добавить индекс так он пытается хранить память в одном и том же месте каждый раз, когда вы проходите цикл, вызывая segfault. Также, как упоминалось в комментариях, вы должны использовать sizeof (Player) вместо sizeof (Player *).

После вашего стиля, он должен быть:

(log.arr + i)->players = (Player*)malloc(7 * sizeof(Player)); 

Я бы предложил сделать команду * обр СТАНД :: вектор и плеер * игрокам зОго :: вектор (если вы хотите динамический контейнер). Вектор позаботится об управлении памятью (через его Allocator) и улучшит читаемость кода и упростит его использование в будущем (повторное использование кода).

+0

Я проверил код, я отлично прочитал 21000 записей, вы абсолютно правы. Большое вам спасибо, я был обеспокоен этим кодом в течение 2 дней. – hitter

2

Поскольку вы используете C++ Я хотел бы предложить вам рекомендации, то, что я собираюсь написать, слишком длинное для doit в комментарии, поэтому было написано как ответ.

Использование умных указателей.

С умным указателем у вас нет (вообще) заботы об управлении памятью.

Ссылки оптоволоконный Interest:

Smart Pointers (Modern C++), Smart pointer

Использование std::string всегда можно.

Вы кодируете с использованием языка C++, иначе не используете его? Вы связываетесь с использованием char?

та же программа (в C++):

#include <iostream> 
#include <vector> 
#include <string> 

typedef struct Player{ 
    std::string firstName; 
    std::string lastName; 
}Player; 

typedef struct Team{ 
    int id; 
    std::string title; 
    std::string summary; 
    int numberOfPlayers; 
    std::vector<Player> players; 
}Team; 

typedef struct TeamsLog{ 
    std::vector<Team> arr; 
    int numberOfTeams; 
}Teams; 


void printstruct(const Team& team) 
{ 
    std::cout << "\nTeam Name: " << team.title 
     << "\nId: " << team.id 
     << "\nSummary: " << team.summary 
     << "\nNumber of players: " << team.numberOfPlayers << std::endl; 


    int index = 0; 
    for (auto &player : team.players) 
    { 
     std::cout << "Player " << ++index << " " << player.firstName << " " << player.lastName << std::endl; 
    } 
} 

int main() 
{ 
    TeamsLog log; 
    log.numberOfTeams = 21000; 
    log.arr.reserve(21000); // This is not really needed but improve performance. 

    for (int i = 0; i < log.numberOfTeams; ++i) 
    { 
     Team team; 
     team.id = 1; 
     team.numberOfPlayers = 7; 

     team.summary = "some summary"; 
     team.title = "some title"; 

     team.players.reserve(7); 

     for (int l = 0; l < 7; ++l) 
     { 
      Player player; 
      player.firstName = "Some name"; 
      player.lastName = "Some last name"; 
      team.players.push_back(player); 
     } 
     log.arr.push_back(team); 
     printstruct(log.arr[i]); 
    } 
} 
+0

На самом деле я использую сочетание как char, так и std :: string Потому что я вынужден основывать свой проект на C++ на тех C-style Structs Кстати, спасибо за ссылки, Я не знал концепции умных указатель до сегодняшнего дня – hitter

Смежные вопросы