0

Hi I'm a beginner at c++ and I'm having trouble solving this issue. I have a linkedlist of nodes and the node contains data of int array and a pointer pointing to the next node.

struct node {
   unsigned int numbers[6];
   node* next;
};

I also have a class:

private:
   ticket* ticketListHead;
   ticket* ticketListTail;

and in a public method:

public:
    void newNode() {

       int arr[6];

       for(int i = 0; i < 6; ++i) {
           arr[i] = ( std::rand() % 49 ) + 1;
       }

       node *temp = new node;
       temp->numbers=arr;
       temp->next=NULL;
}

The problem I believe is with the temp->numbers=arr line as I believe arrays cannot be assigned like that in C++. I'm not sure how to solve the problem in this case and I've tried looking online. Some help would be appreciated!

Samm
  • 105
  • 1
  • 2
  • 8
  • 1
    Are you allowed to use `std::array`? – NathanOliver Mar 11 '19 at 16:32
  • I believe so. What would I method would I use? – Samm Mar 11 '19 at 16:33
  • 2
    **WARNING**: Using [`rand()` is highly problematic](https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful) and you’re strongly encouraged to use an appropriate [random number generator facility in the Standard Library](http://en.cppreference.com/w/cpp/numeric/random) that produces high-quality random values. Your use of `time(NULL)` as a random number seed means that this will produce identical results if run in the same second, and on many platforms `rand()` is [*barely* random at all](http://dilbert.com/strip/2001-10-25). – tadman Mar 11 '19 at 16:34
  • @Samm Just move the loop to the end of `newNode()`, and write directly to `temp->numbers[i]` rather than `arr[i]`. – HolyBlackCat Mar 11 '19 at 16:35
  • Instead of C-style arrays, use `std::vector` or [`std::array`](https://en.cppreference.com/w/cpp/container/array) depending on if you need fixed-length or variable length. These are much easier to pass around and have a number of other key features, like a robust set of iterators. – tadman Mar 11 '19 at 16:35
  • 1
    Why doesn't `node` have a constructor? It probably should to avoid initializing it incorrectly or forgetting to populate `next` and such. – tadman Mar 11 '19 at 16:36
  • new up your node and then assign it's arr elements in your loop I.e. `temp->numbers[i] = ( std::rand() % 49 ) + 1;` – George Mar 11 '19 at 16:37
  • No, you cannot assign raw arrays but you can assign `std::arrays`. – Jabberwocky Mar 11 '19 at 16:38

3 Answers3

1

You're correct about your suspicion that you cannot assign arrays. You could instead use a wrapper type that allows assignment and define

using array = std::array<unsigned,6>;  // convenient short hand
struct node {
    array numbers; 
    node* next = nullptr;              // ensure next defaults to null
};

when your newNode() method may look like

node* newNode() {
    array arr;
    for(auto&x: arr)
        x = ( std::rand() % 49 ) + 1;   // std::rand() cannot be recommended
    auto temp = new node;
    temp->numbers = arr;
    return temp;
}

but you can avoid the temporary object arr altogether by directly writing into the new node's data:

node* newNode() {
    auto temp = new node;
    for(auto&x: temp->numbers)
        x = ( std::rand() % 49 ) + 1;   // std::rand() cannot be recommended
    return temp;
}

Btw, you shouldn't use std::rand() (see this post and this presentation for reasons why). Instead, use the methods provided by <random>, when your code becomes (see also this answer)

template<typename Generator>
node* newNode(Generator&rng) {
    std::uniform_int_distribution<unsigned> uni(1,49);
    auto temp = new node;
    for(auto&x: temp->numbers)
        x = uni(rng);             // guaranteed unbiased in [1,49] inclusive
    return temp;
}
Walter
  • 44,150
  • 20
  • 113
  • 196
0

Welcome to C++, it's awesome that you're taking your first steps into a brighter world! What you'll want to look into are C++ container classes, they'll get you out of the business of managing memory on your own. The closest to your code is std::list and std::vector. I'll neglect random number seeding, that's a complex topic better discussed elsewhere.

#include <vector>
#include <list>
#include <iostream>
#include <random>
#include <limits>
using namespace std;
struct node {
  node() : num(6) {
    numbers.reserve(num);
    for (int i = 0; i < num; ++i)
      numbers.push_back(random() % numeric_limits<int>::max());
  }
  vector<int> numbers;
  const int num;
};

int main(int argc, char** argv) {
  list<node> nodes;
  nodes.push_back(node()); // this replaces your newNode function
  nodes.push_back(node()); // another call to better illustrate
  for (auto mynode : nodes) {
    for (auto mynum : mynode.numbers)
      cout << mynum << " ";
    cout << endl;
  }
}
-1
// Change node struct to this 
struct node{
unsigned int *numbers;
node* next;
};

/*
Remember that normal arrays are 
implemented through pointers. So you 
can use a pointer named numbers in 
your node struct and it would behave 
as an array.
*/

// Change newNode() to this 
void newNode() {
int * arr = new int[6]; //Dynamic memory allocation
for(int i = 0; i < 6; ++i) 
{ 
arr[i] = ( std::rand() % 49 ) + 1; 
}
node *temp = new node; 
temp->numbers = arr; 
temp->next = NULL;
}

U got it ?