2017-01-29 5 views
0

Я написал следующий код. Он хорошо работает на некоторых входах, но показывает ошибку на некоторых других.Следующий код на C++ дает некоторую ошибку выделения памяти

Например, при попытке ввода:

он показывает следующее сообщение об ошибке так же, как я ввести второй (без ожидания третьей линии)

a.out: malloc.c:2395: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. 
Aborted (core dumped) 

В чем может быть причина?

#include <iostream> 
#include <list> 
#include <cmath> 
using namespace std; 

void addEdge(list<int> *adj, int a, int b) 
{ 
    adj[a].push_back(b); 
} 

int count = 1; 
int dfsVisit(int i, bool *visited,list<int> *adj) 
{ 
    visited[i] = true; 
    list<int> ::iterator k; 
    for(k=adj[i].begin(); k!=adj[i].end();k++) 
    { 
     if(!visited[*k]) 
     { 
      count ++; 
      dfsVisit(*k, visited, adj); 

     } 
    } 
    return count; 
} 

int main() 
{ 
    list<int> *adj; 
    long int n,i,j,a,b,m=0,k; 
    long int arr[1000000]; 
    cin>>n>>i; 
    bool *visited = new bool; 
    for(j=0;j<n;j++) 
    { 
     visited[j] = false; 
    } 
    adj = new list<int>[n]; 
    for(j=0;j<i;j++) 
    { 
     cin>>a>>b; 
     addEdge(adj, a,b); 
    } 
    for(k=0;k<n;k++) 
    { 
     if(visited[k]==false) 
     { 
      count = 1; 
      arr[m] = dfsVisit(k, visited, adj); 
      m++; 
     } 
    } 

    /*for(k=0;k<m;k++) 
    { 
     cout<<arr[k]; 
    }*/ 
     long int ans = 1; 
    if(m>1) 
    { 

     for(k=0;k<m;k++) 
     { 
      ans = ans * arr[k]; 
     } 

    } 
    if(m==1) 
    { 
     ans = 0; 
    } 

    cout<<ans; 

} 
+0

Посещение не имеет выделенной памяти. – Shiping

+1

Помните, что локальные переменные, включая массив, обычно хранятся в стеке и что стек ограничен. Например, размер стека по умолчанию в Windows - это один MB. В Linux размер стека по умолчанию составляет 8 МБ. Ваш массив 'arr' в функции' main' сам по себе составляет почти 8 МБ в системе с 64-разрядной «длинной» (например, типичной 64-битной системой Linux). Ты живешь на краю! –

+0

Я абсолютно уверен, что вы не хотите 'adj = новый список [n];'. Вам не нужны 'n списки'. Контраст с 'новым bool', где вам на самом деле *** нужно ***' n bools'. Также ваши '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' –

ответ

1

Вы только что объявили, что посетили его как указатель, но выделили только один слот памяти.

bool *visited = new bool; 
for(j=0;j<n;j++) 
{ 
    visited[j] = false; 
} 
+1

@CraigYoung только что осознал это и исправил его. ;-) – Shiping

+0

Как вы это исправите? –

+0

@AlanStokes в этом конкретном случае, вы можете сделать bool * visited = new bool [n]; – Shiping

1

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

C++ действительно менее подвержен ошибкам, чем C, и следует использовать это.

#include <iostream> 
#include <list> 
#include <cmath> 
#include <vector> 
#include <cstddef> 

using namespace std; 

void addEdge(std::vector<std::list<std::size_t>>& adj, 
    std::size_t a, std::size_t b) 
{ 
    adj.at(a).push_back(b); 
} 

void dfsVisit(std::size_t i, std::vector<bool>& visited, 
    std::vector<std::list<std::size_t>> const& adj, std::size_t& count) 
{ 
    visited[i] = true; 
    for (auto k : adj.at(i)) 
    { 
     if (!visited.at(k)) 
     { 
      ++count; 
      dfsVisit(k, visited, adj, count); 
     } 
    } 
} 

int main() 
{ 

    // initialize all variables and make the scope as small as possible 
    std::size_t ni{}, ii{}; 
    // try to read n and i from cin 
    // without the if you never know that you'll actually have valid input 
    if (std::cin >> ni >> ii) 
    { 
     // const refs to block changes 
     auto const& n = ni; 
     auto const& i = ii; 
     // dynamic, contiguous memory ? -> std::vector ! 
     // create visited vector 
     // no need to loop: we can make them all false here 
     auto visited = std::vector<bool>(n, false); 
     // create adj vector 
     auto adj = std::vector<std::list<std::size_t>>(n); 
     // you don't need arr on the stack so don't put it there 
     std::vector<std::size_t> arr; 
     // we know we'll have at max n entries in arr 
     arr.reserve(n); 
     // add edges 
     for (std::size_t j = 0u; j < i; ++j) 
     { 
      std::size_t a{}, b{}; 
      if (std::cin >> a >> b) 
      { 
       addEdge(adj, a, b); 
      } 
      // TODO: else clause when input fails... 
     } 
     std::size_t count{}; 
     for (std::size_t k = 0u; k < n; ++k) 
     { 
      if (!visited[k]) 
      { 
       std::size_t count = 1u; 
       dfsVisit(k, visited, adj, count); 
       // we know k < n and m < k since we increment at max once 
       // so no at but operator[] 
       arr.push_back(count); 
      } 
     } 
     std::size_t ans = 1u; 
     auto const m = arr.size(); 
     if (m > 1u) 
     { 
      for (std::size_t k = 0; k < m; ++k) 
      { 
       ans = ans * arr[k]; 
      } 
     } 
     else if (m == 1) 
     { 
      ans = 0u; 
     } 

     std::cout << ans; 

    } 
    // TODO: else clause when input fails... 

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