Reputation: 119
Hello I am dealing with nested structs and arrays in C++, here is some background info:
struct Cells // a collection of data cells lines
cells :: [Cell] // the cells: a location and a value
nCells :: Integer // number of cells in the array
capacity :: Integer // maximum size of the array end
struct Cell
location :: int // a location of data cells lines
value :: int // the value end Cells
The code I have which won't compile (3 files, header, ADT implementation, main) How am I declaring the nested struct in struct array wrong?
// Defines the cell.h ADT interface
struct Cell;
struct Cells;
struct Cells {
Cell cells[];
int nCells;
int capacity;
};
struct Cell {
int location;
int value;
};
//fill cells with random numbers
void initialize(Cells *rcells);
ADT Implementation
using namespace std;
#include <iostream>
#include <cstdlib>
#include "cell.h"
void initialize(Cells *rcells){
for(int i = 0 ; i < rcells->nCells; i++)
{
rcells->cells[i].location = rand() % 100;
rcells->cells[i].value = rand() % 1000;
}
}
main
using namespace std;
#include <iostream>
#include <cstdlib>
#include "cell.h"
int main(){
Cells *c;
c->cells[0].location=0;
c->cells[0].value=0;
c->cells[1].location=0;
c->cells[1].value=0;
c->nCells = 2;
c->capacity = 2;
initialize(c);
}
Upvotes: 1
Views: 3132
Reputation: 233
Your original declaration fails because in
struct Cells {
Cell cells[];
int nCells;
int capacity;
};
"cells" defined in this way is an array, which should have fixed size (unless it is the last member and you're using C99 standard). You may think it is the same as
Cell* cells
but it won't be converted to pointer type automatically in struct definition.
The C++ way to do such things is
typedef std::vector<Cell> Cells;
Your initialize function could be
void initialize(int ncell, Cells& cells) {
cells.resize(ncell);
for (Cell& cell : cells)
{
cell.location = rand() % 100;
cell.value = rand() % 1000;
}
}
Your main program should change a little bit
int main(){
Cells c;
initialize(2, c);
c[0].location=0;
c[0].value=0;
c[1].location=0;
c[1].value=0;
}
If you want cell count information, you can call
c.size()
There is no need for capacity variable because there is no upper limit on total number of cells.
By the way, this is not the nested struct people usually talk about. When one say nested struct, he often means nested struct definition. There is nothing special about an object containing other objects.
Upvotes: 2
Reputation: 3142
Unlike some other programming languages, when you declare an array in C or C++, it is created where you declare it. For example if you declare one as a function local variable, it will be created on the stack.
In you case Cell cells[];
declares an array that must be created within your class. Thus if you class have an array of four elements, the compiler needs to allocate to each instance 4*sizeof(Cell)
bytes for the field so it can fit the array in the instance. If your array have 524 elements, it needs 524*sizeof(Cell)
bytes.
You see the problem here : the compiler cannot guess what is the size of your object. Which is problematic to obtain the location of each field in an instance, especially if you declare two array without size. Note that this issue is not restricted to object fields : you cannot declare an array as a local variable in a function without giving a size either, for example. This because array have a fixed size determined upon creation. Thus wherever you create the array, you must provide its size.
When you write Cell array[]
as a function argument, you are not creating an array, but only obtaining a pointer to it, so not giving its size is okay.
To solve your issue you must somehow make classes with a constant size. For example you can allocate you array dynamically with new[some_variable]
and use pointer Cell *cells;
in your class. A pointer has a fixed size, and you array is to be declared on the heap (don't forget to delete[]
it).
Remark: instead of a size, giving an array initializer only is valid :
int x[] = {1, 2, 4}; //creates an array of three elements
Upvotes: 0