I want to have a linked list, with a variable which has dynamic size,
because I want to just allocate different sizes for a variable in different nodes. for example node1 has a array variable with size 1, but node 2 has a array variable with size 10, and node3 never allocates this array.
like this:
struct st{
int * var_dynamic;
int x;
};
now I want to initialize them. for the static one, it is like this:
struct st st1;
st1.x=1;
but how can I initialize the dynamic one?
Is it something like this?
st1.var_dynamic= new int [100];
and if yes, Is this way correct and efficient?
The most idiomatic, straightforward, and safe solution is to simply use std::vector:
struct st
{
std::vector<int> var_dynamic;
int x;
};
For using std::vector, consult a reference documentation, or your favourite book.
Related
I have a double pointer Array of a structure:
typedef struct Position{
int x;
int y;
} Position;
Position** array = (Position**)malloc(sizeof(Position*)*10); //10 elements
array[0] = (Position*)malloc(sizeof(Position*));
array[0]->x = 10;
array[0]->y = 5;
Can I calculate the length of set array and if so, how?
The normal way for arrays does not work :
int length = sizeof(<array>)/sizeof(<array>[0]);
Once you have dynamically allocated an array, there is no way of finding out the number of elements in it.
I once heard of some hacky way to obtain the size of a memory block, (msize) which would allegedly allow you to infer the size of the data within the block, but I would advice against any such weird tricks, because they are not covered by the standard, they represent compiler-vendor-specific extensions.
So, the only way to know the size of your array is to keep the size of the array around. Declare a struct, put the array and its length in the struct, and use that instead of the naked array.
As you marked the question as C++, I would suggest that you use std::vector, then, after you "allocated some memory" (or requested some memory to allocated by std::vector constructor or by using push_back, or resize), you can simply get the size back using by using std::vector::size.
typedef struct Position{
int x;
int y;
} Position;
std::vector<Position> array(10);
array[0].x = 10;
array[0].y = 5;
size_t size = array.size(); // will be 10
Having only a pointer to some memory block, you cannot defer the size of this memory block. So you cannot defer the number of elements in it.
For arrays of pointers, however, you could infer the number of elements in it under the following conditions:
make sure that every pointer (except the last one) points to a valid object.
for the last pointer in the array, make sure that it is always NULL.
Then you can derive the length by counting until you reach NULL.
Maybe there are some other similar strategies.
Solely from the pointer itself, however, you cannot derive the number of elements in it.
Old question, but in case someone needs it:
#include <stdio.h>
...
int main()
{
char **double_pointer_char;
...
int length_counter = 0;
while(double_pointer_char[length_counter])
length_counter++;
...
return 0;
}
I was curious as to what will be a better way to initalise an array in C++?
Will it be:
int array[50];
or
int x;
cin>> x; //Input a number to initialise the array.
int array[x];
Which of these two will be a better option to initialise an array and why? If none, then is there a third way?
If you want a static array(const number of items), use std::array:
std::array<int,50> a;
If you want a dynamic array(non const number of array), use std::vector:
std::vector<int> a(50);
in this case you can change the size of the vector any time you want by resizing it:
a.resize(100);
or just by pushing new items:
a.push_back(5);
read more about std::vector. It can serve you more than you can imagine.
P.S. the second code of your question is not valid (or at least it is not standard). However, you can do this instead:
int x;
cin>> x; //Input a number to initialise the array.
std::vector<int> array(x);
If you know the size of an array at compile time, and it will not change, then the best way is:
std::array<int, 50> arr;
Otherwise use
std::vector<int> arr;
I'm trying to make a dynamically allocated bidimensional array with variable size but I don't know why if I create my own constant value it won't compile:
const int oConstanta=N+1;
int (*m)[oConstanta]=new int[oConstanta][oConstanta];
But when I use a normal constant such as 1000 between the brackets it compiles successfully.
const int oConstanta=N+1;
int (*m)[1000]=new int[1000][1000];
Does anyone know the reason for this?
PS: I know that:
int **m=new int*[oConstanta];
for(i=1;i<=N;i++)
{
m[i]=new int[oConstanta];
init(m[i]);
}
will solve my problems but I want to learn why my former method was a bad idea.
Unless N is a compile-time constant expression, oConstanta is not a compile-time constant either.
The best way of making a two-dimensional array in C++ is using std::vector of std::vectors, for example, like this:
#include <vector>
std::vector<std::vector<int> > m(N+1, std::vector<int>(N+1, 0));
Ultimately the reason is that you can't create static arrays of variable length.
In your code you are trying to create a static array of dynamic arrays, both of variable length.
Now, static arrays live in the stack, while dynamic arrays live in the heap. While the memory management of the heap is "flexible", the stack is different: the compiler needs to be able to determine the size of each frame in the stack. This is clearly not possible if you use an array of variable length.
On the other hand, if you use a pointer the size of the stack frame is known (a pointer has a known size) and everything is fine.
If you want to try, this should compile fine
int (*m)[1000]=new int[oConstanta][1000]
since it's a fixed-size static array, whose entries are dynamically allocated arrays of variable length (allowed).
In short: whenever the size of an object is not known at compile time, that object cannot be in the stack, it has to be dynamically allocated.
To make a dynamically sized, 2D matrix with contiguous elements and a single allocation:
std::vector<int> matrix(Rows*Columns);
Access an element in the i th row and j th column:
matrix[Columns*i + j] = 1;
You can wrap this all up in a class. Here's a very basic example:
struct Matrix {
std::vector<int> m;
size_t rows,columns;
Matrix(size_t rows,size_t columns)
: rows(rows)
, columns(columns)
, m(rows*columns)
{}
int &at(size_t i,size_t j) {
return m.at(i*columns + j);
}
};
I've got a static map of identifier<=>struct pairs, and each struct should contain some arrays. Everything is known at compile time. That is, I want to have something like this here:
ID1 => name: someString
flagCount: 3
flags: [1, 5, 10]
statically created (if possible). Of course, a declaration like:
struct Info
{
const char* name;
int flagCount;
int flags[];
};
would be ideal, as long as I could initialize it like ...
Info infos [] = { ... };
which is not possible, due to the varying length arrays (except I'm missing something). Alternatively, I though about (ab)using boost::assign for this, but I'm wondering if there is a recommended solution to this. I'm fine if I can store only the info structures into an array, and to the mapping elsewhere.
Edit: A note on the current solution. At the moment, I have:
struct Info
{
Info (const std::vector<int>& flags) : flags {}
std::vector<int> flags;
};
and I use:
const std::map<ID, Info> map = boost::assign::map_list_of
("ID1", Info (boost::assign::list_of (1)(2)(3));
which works, I'm just curious whether there is a simpler solution (template-based?).
The elements in an array must be the same size as each other, otherwise you can't use infos[i] to access them - the compiler would have to step through the array and look at the size of each element up to i to find where the next one started. You can allocate enough memory for each element contiguously, and then create an array of pointers to the elements (pointers being a fixed size). If you only need the mapping and not to index the infos then your map will be identifier to pointer.
Alternatively, as you know the size at compile time, if there are only a few flags, make the Info::flags array large enough for the maximum flags, or make it a pointer to an array of flags, so that Info is a fixed size struct.
Either use a pointer to the variable-length array:
struct Info
{
const char* name;
int flagCount;
int *flags;
};
or fixed-size array large enough to hold all flags:
struct Info
{
const char* name;
int flagCount;
int flags[MAX_FLAGS];
};
Both solutions will waste some memory; but for solution 1, it's just one pointer per struct; note that you are already implicitly using this solution for the name field.
Using a vector as you have done is almost certainly the best solution. oefe has given you a solution where you include some indirection in the Info's themselves, another option is to indirect in the map, i.e. map<ID, Info*> (or since you're using boost map<ID, shared_ptr<Info> >) and define Info like. Actually don't do this. Use a vector. It's the best solution.
struct Info {
const char *name;
int flagCount;
int flags[1]; // this is cheating...
};
Info* make_info(int count) {
char *buf = new char[sizeof(Info) + (sizeof(int) * (count - 1))];
Info *rv = static_cast<Info*>(static_cast<void*>(buf));
rv->flagCount = count;
}
we have a data structure
struct MyData
{
int length ;
char package[MAX_SIZE];
};
where MAX_SIZE is a fixed value . Now we want to change it so as to support
"unlimited" package length greater than MAX_SIZE . one of the proposed solution
is to replace the static array with a pointer and then dynamically allocating
the size as we require For EX
struct MyData
{
int length ;
char* package;
};
and then
package = (char*)malloc(SOME_RUNTIME_SIZE) ;
Now my question is that is this the most efficient way to cater to the requirement OR is there any other method .. maybe using STL data structures like growable arrays etc etc .
we want a solution where most of the code that works for the static char array should work for the new structure too ..
Much, much better/safer:
struct my_struct
{
std::vector<char>package;
};
To resize it:
my_struct s;
s.package.resize(100);
To look at how big it is:
my_struct s;
int size = s.package.size();
You can even put the functions in the struct to make it nicer:
struct my_struct
{
std::vector<char>package;
void resize(int n) {
package.resize(n);
}
int size() const {
return package.size();
}
};
my_struct s;
s.resize(100);
int z = s.size();
And before you know it, you're writing good code...
using STL data structures like growable arrays
The STL provides you with a host of containers. Unfortunately, the choice depends on your requirements. How often do you add to the container? How many times do you delete? Where do you delete from/add to? Do you need random access? What performance gurantees do you need? Once you have a sufficiently clear idea about such things look up vector, deque, list, set etc.
If you can provide some more detail, we can surely help pick a proper one.
I would also wrap a vector:
// wraps a vector. provides convenience conversion constructors
// and assign functions.
struct bytebuf {
explicit bytebuf(size_t size):c(size) { }
template<size_t size>
bytebuf(char const(&v)[size]) { assign(v); }
template<size_t size>
void assign(char const(&v)[size]) {
c.assign(v, v+size);
}
// provide access to wrapped vector
std::vector<char> & buf() {
return c;
}
private:
std::vector<char> c;
};
int main() {
bytebuf b("data");
process(&b.buf()[0], b.buf().size()); // process 5 byte
std::string str(&b.buf()[0]);
std::cout << str; // outputs "data"
bytebuf c(100);
read(&c.buf()[0], c.buf().size()); // read 100 byte
// ...
}
There is no need to add many more functions to it, i think. You can always get the vector using buf() and operate on it directly. Since a vectors' storage is contiguous, you can use it like a C array, but it is still resizable:
c.buf().resize(42)
The template conversion constructor and assign function allows you to initialize or assign from a C array directly. If you like, you can add more constructors that can initialize from a set of two iterators or a pointer and a length. But i would try keeping the amount of added functionality low, so it keeps being a tight, transparent vector wrapping struct.
If this is C:
Don't cast the return value of malloc().
Use size_t to represent the size of the allocated "package", not int.
If you're using the character array as an array of characters, use a std::vector<char> as that's what vectors are for. If you're using the character array as a string, use a std::string which will store its data in pretty much the same way as a std::vector<char>, but will communicate its purpose more clearly.
Yep, I would use an STL vector for this:
struct
{
std::vector<char> package;
// not sure if you have anything else in here ?
};
but your struct length member just becomes package.size ().
You can index characters in the vector as you would in your original char array (package[index]).
use a deque. sure a vector will work and be fine, but a deque will use fragmented memory and be almost as fast.
How are you using your structure?
Is it like an array or like a string?
I would just typedef one of the C++ containers:
typedef std::string MyData; // or std::vector<char> if that is more appropriate
What you have written can work and is probably the best thing to do if you do not need to resize on the fly. If you find that you need to expand your array, you can run
package = (char*)realloc((void*)package, SOME_RUNTIME_SIZE) ;
You can use an STL vector
include <vector>
std::vector<char> myVec(); //optionally myVec(SOME_RUNTIME_SIZE)
that you can then resize using myVec.resize(newSize) or by using functions such as push_back that add to the vector and automatically resize. The good thing about the vector solution is that it takes away many memory management issues -- if the vector is stack-allocated, its destructor will be called when it goes out of scope and the dynamically-allocated array underlying it will be deleted. However, if you pass the vector around, the data will get copied that can be slow, so you may need to pass pointers to vectors instead.