Can I specify the location of the heap to serialize my data? - c

I want to store a program state in a file. So I have a mmapped file that I perform operations on and then save it and maybe use it later.
This is fine for simple things but if I want a long lived data structure that requires dynamic memory allocation, I need a memory allocator that I can force to allocate within the pages I have mmapped.
I'm fairly certain I can't do this with the standard c malloc, and I've looked at jemalloc and I don't know if I can see anything there. I don't know if I'm going the wrong way with this, but is there any way to specify the location/size of heap before it is used?

For something like this you don't really want dynamic memory allocation. What you want instead is an array which uses an index value of the pointed to element instead of an actual pointer.
Suppose you wanted to implement a binary tree. You can model it as follows:
struct tree {
int free;
int value;
int left;
int right;
};
The left and right fields contain the indexes of the nodes to the left and to the right of the given node, with the value -1 indicating no such node (i.e. it is equivalent to a NULL pointer in this context).
The free field can be used as a flag to determine whether a given element of the array is currently in use. If a node is marked with free equal to 1, the left field points to the next free node, making it easy to find free nodes.
Node 0 is special in that it is the start of the free list, and the right field points to the root node of the tree.
Then the following tree:
7
/ \
3 10
/ \ / \
1 4 8 12
Can be modeled as follows:
free value left right
---------------------------
0 | 1 | 0 | 8 | 1 |
---------------------------
1 | 0 | 7 | 2 | 3 |
---------------------------
2 | 0 | 3 | 4 | 5 |
---------------------------
3 | 0 | 10 | 6 | 7 |
---------------------------
4 | 0 | 1 | -1 | -1 |
---------------------------
5 | 0 | 4 | -1 | -1 |
---------------------------
6 | 0 | 8 | -1 | -1 |
---------------------------
7 | 0 | 12 | -1 | -1 |
---------------------------
8 | 1 | 0 | 9 | -1 |
---------------------------
9 | 1 | 0 | -1 | -1 |
---------------------------
Such a tree can either be memmapped, or kept in memory using malloc / realloc to manage the size.
If your data structure holds any kind of string, you'll want your structure to contain fixed size character arrays instead of pointers so that they serialize correctly.

Related

How does strlen(&string[]) work?

This might be a bit long question. I was testing some character arrays in C and so came along this code.
char t[10];
strcpy(t, "abcd");
printf("%d\n", strlen(&t[5]));
printf("Length: %d\n", strlen(t));
Now apparently strlen(&t[5]) yields 3 while strlen(t) returns 4.
I know that string length is 4, this is obvious from inserting four characters. But why does strlen(&t[5]) return 3?
My guess is that
String: a | b | c | d | 0 | 0 | 0 | 0 | 0 | \0
Position: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
strlen(&t[5]) looks at the length of a string composed of positions 6, 7 and 8 (because the 10th character is a NULL terminating character, right)?
OK, then I did some experimentation and modified a code a bit.
char t[10];
strcpy(t, "abcdefghij");
printf("%d\n", strlen(&t[5]));
printf("Length: %d\n", strlen(t));
Now this time strlen(&t[5]) yields 5 while strlen(t) is 10, as expected. If I understand character arrays correctly, the state should now be
String: a | b | c | d | e | f | g | h | i | j | '\0'
Position: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
so why does strlen(&t[5]) return 5 this time? I've declared a character array of length 10, should then, by the same logic applied above, the result be 4?
Also shouldn't I be running into some compiler errors since the NULL terminating character is actually in the 11th spot? I'm new into C and would very much appreciate anyone's help.
First let me tell you, your "assumption"
String: a | b | c | d | 0 | 0 | 0 | 0 | 0 | \0
Position: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
is not correct. Based on your code, The values are only "guaranteed" up to index 4, not beyond that.
For the first case, in your code
printf("%d\n", strlen(&t[5]));
is wrong for various reasons,
you ought to use %zu for a size_t type.
&t[5] does not point to a valid string.
Any (or both) of the above causes undefined behavior and any output cannot be justified.
To elaborate, with a defintion like
char t[10];
strcpy(t, "abcd");
you have index 0 to 3 populated for t, and index 4 holds the null-terminator. The content of t[5] onward, is indeterminate.
Thus, &t[5] is not a pointer to the first element of a string, so cannot be used argument to strlen().
It may run out of bound in search of the null-terminator and experience invalid memory access and, as a side-effect, produce a segmentation fault,
It may find a null-terminator (just another garbage value) within the bound and report a "seemingly" valid length.
Both are equally likely and unlikely, really. UB is UB, there's not justifying it.
Then, for the second case, where you say
char t[10];
strcpy(t, "abcdefghij");
is once again, accessing memory out of bound.
You have all together 10 array elements to store a string, so you can have 9 other char elements, plus one null-terminator (to qualify the char array as a string).
However, you're attempting to put 10 char elements, plus a null character (in strcpy()), so you're off-by-one, accessing out of bound memory, invoking UB.
char t[10]; is not initialized so it just contains garbage values 1). strcpy(t, "abcd"); overwrites the first 5 characters with the string "abcd" and a null terminator.
However, &t[5] points at the first character after the null termination, which remains garbage. If you invoke strlen from there, anything can happen, since the pointer passed is not likely pointing at a null terminated string.
1) Garbage = indeterminate values. Assuming a sane 2's complement system, the address of the buffer t is taken, so the code does not invoke undefined behavior until the point where strlen starts reading outside the bounds of the array t. Reference.
Problem 1:
My guess is that
String: a | b | c | d | 0 | 0 | 0 | 0 | 0 | \0
Position: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
This assumption is wrong.
The array is not initialized to hold 0 values but contains some "random" garbage.
After copying "abcd" the upper half of the array (t[5] etc.) is still untouched resulting in a "random" length of the string due to undefined behaviour.
Problem 2:
If I understand character arrays correctly, the state should now be
String: a | b | c | d | e | f | g | h | i | j | '\0'
Position: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
Again wrong.
Your array only holds 10 characters. Theyare at index 0..9. Index 10 is out of bounds.
Your copy operation might result in this layout or it might as well just crash while writing out of bounds.
But this is not checked by the compiler. If you run into problems then it will be during runtime.

Can't pass multidimensional array to structure

typedef struct arg_struct {
struct GPU_FFT *fft;
struct GPU_FFT_COMPLEX *base;
float **input;
float *output;
int number;
} arg_struct;
...
arguments[0].input = **Queue;
arguments[1].input = *(*(Queue)+QueueSize[0]);
My multidimensional array is Queue[2][1025]. I am trying to pass Queue[0][0] and Queue[1][0] into my arguments structure. It gives me "error: incompatible types when assigning to type ‘float **’ from type ‘float’" error. As a rookie programmer, I've tried so many variations but still couldn't figure out how to pass them.
By the way, QueueSize[0] is an integer which has value of 1025.
You can solve your problem very easily, by making the input member a simple pointer:
float *input;
Then you can make each pointer point to the corresponding array of Queue:
arguments[0].input = Queue[0];
arguments[1].input = Queue[1];
Be careful though, the lifetime of Queue must be at least as long as the lifetime of arguments. If Queue goes out of scope then the pointers will be stray, and can no longer be used. If Queue can go out of scope then you need to create full arrays of (or allocate memory for) the input member, and copy the contents into that memory.
There is big difference between 2d array and pointer to pointer.
In your struct is pointer to pointer, so you have to init it like
arguments[0].input = malloc(sizeof(float *) * num_of_rows);
for (int i = 0; i < num_of_rows; i++)
{
arguments[0].input[i] = malloc(sizeof(float) * num_of_cols);
}
Dont forget to free all the allocated memory. You can use valgrind for checking memory leaks.
2D array is sequence of bytes in memory
0 1 2 3
+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 // begins on address 1000
+---+---+---+---+
| 0 | 0 | 0 | 0 | 1 // begins on address 1004
+---+---+---+---+
| 0 | 0 | 0 | 0 | 2 // begins on address 1008
+---+---+---+---+
| 0 | 0 | 0 | 0 | 3 // begins on address 1012
+---+---+---+---+
while array of pointers, where every pointer can point to another part of memory
0 1 2 3
+---+---+---+---+
| * | * | * | * |
+---+---+---+---+
| | | |
| | | | 0 1 2 3
| | | | +---+---+---+---+
| | | -> | 0 | 0 | 0 | 0 | // begins on address 1000
| | | +---+---+---+---+
| | -----> | 0 | 0 | 0 | 0 | // begins on address 2
| | +---+---+---+---+
| ---------> | 0 | 0 | 0 | 0 | // begins on address 3045
| +---+---+---+---+
-------------> | 0 | 0 | 0 | 0 | // begins on address 128
+---+---+---+---+

SUMPRODUCT doesn't recognise OFFSET array

I'm working through an Excel exercise in which I need to SUMPRODUCT two tables of related values. Unfortunately, I can't be sure the tables will always be ordered identically.
To get around this, I have looked up their values into a new third table; this works, however I'm now looking for a way to do it in one cell.
My code is currently
SUMPRODUCT(Resources_Used18[In House],OFFSET(Rate_comparison[Role],MATCH(Resources_Used18[Role],Rate_comparison[Role],0)-1,1))
For some reason however this doesn't seem to work and only ever returns zeros. The OFFSET(,MATCH()) is meant to reconstruct the second data array, this appears to work and when I test it with F9 it produces the array I'm expecting.
Additionally when I manually enter the array, it provides the correct answer.
So I think the error must be with SUMPRODUCT failing to recognise it as an array.
Where is the error and how can I correct my formula? Thanks for your help.
EDIT: Actually I need to correct myself, OFFSET produce the correct array when run in a cell of its however after I run the cell if I don't ctrl-shift-enter then produces an array of errors.
EDIT:EDIT: An example of the sort of data I'm looking is this,
Rate_comparison
| Role | Rate |
|------|------|
| 1 | 50 |
| 2 | 100 |
| 3 | 150 |
| 4 | 200 |
| 5 | 250 |
| 6 | 300 |
| 7 | 350 |
| 8 | 400 |
| 9 | 450 |
And
Resources_Used18
| Role | In house |
|------|----------|
| 9 | 23 |
| 8 | 24 |
| 4 | 25 |
| 3 | 26 |
| 1 | 27 |
| 7 | 28 |
| 6 | 29 |
| 5 | 30 |
| 2 | 31 |
I have seen this issue before, and cannot explain it. However, if you enclose the OFFSET function inside the N function, the actual values will be returned.
I did not check to see if the result (59,300) is correct however.
=SUMPRODUCT(Resources_Used18[ [ In house ] ],N(OFFSET(Rate_Comparison[ [ Role ] ],MATCH(Resources_Used18[ [ Role ] ],Rate_Comparison[ [ Role ] ],0)-1,1)))
According to Tushar Metar, The OFFSET function, when used with an array as the 2nd or 3rd argument, returns an undocumented data structure that is understood only by Excel.  The N function converts the data from the internal structure into one that can be displayed or used for further analysis.  Laurent Longre deserves the credit for discovering this capability of the N function.

Creating hierarchical data (tree) structures in Neo4j using "tree keys"

I have imported data from a CSV file and created a lot of Nodes, all of which are related to other Nodes within the same data set based on a "Tree Number" hierarchy system:
For example, the Node with Tree Number A01.111 is a direct child of Node A01, and the Node with Tree Number A01.111.230 is a direct child of Node A01.111.
What I am trying to do is create unique relationships between Nodes that are direct children of other Nodes. For example Node A01.111.230 should only have one "IS_CHILD_OF" relationship, with Node A01.111.
I have tried several things, for example:
MATCH (n:Node), (n2:Node)
WHERE (n2.treeNumber STARTS WITH n.treeNumber)
AND (n <> n2)
AND NOT ((n2)-[:IS_CHILD_OF]->())
CREATE UNIQUE (n2)-[:IS_CHILD_OF]->(n);
This example results in creating unique "IS_CHILD_OF" relationships but not with the direct parent of a Node. Rather, Node A01.111.230 would be related to Node A01.
I'd like to suggest another general solution, also avoiding a cartesian product as #InverseFalcon points out.
Let's indeed start by creating an index for faster lookup, and inserting some test data:
CREATE CONSTRAINT ON (n:Node) ASSERT n.treeNumber IS UNIQUE;
CREATE (n:Node {treeNumber: 'A01.111.230'})
CREATE (n:Node {treeNumber: 'A01.111'})
CREATE (n:Node {treeNumber: 'A01'})
Then we need to scan all nodes as potential parents, and look for children which start with the treeNumber of the parent (STARTS WITH can use the index) and have no dots in the "remainder" of the treeNumber (i.e. a direct child), instead of splitting, joining, etc.:
MATCH (p:Node), (c:Node)
WHERE c.treeNumber STARTS WITH p.treeNumber
AND p <> c
AND NOT substring(c.treeNumber, length(p.treeNumber) + 1) CONTAINS '.'
RETURN p, c
I replaced the creation of the relationship by a simple RETURN for profiling purposes, but you can simply replace it by CREATE UNIQUE or MERGE.
Actually, we can get rid of the p <> c predicate and the + 1 on the length by pre-computing the actual prefix which should match:
MATCH (p:Node)
WITH p, p.treeNumber + '.' AS parentNumber
MATCH (c:Node)
WHERE c.treeNumber STARTS WITH parentNumber
AND NOT substring(c.treeNumber, length(parentNumber)) CONTAINS '.'
RETURN p, c
However, profiling that query shows that the index is not used, and there is a cartesian product (so we have a O(n^2) algorithm):
Compiler CYPHER 3.0
Planner COST
Runtime INTERPRETED
+--------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+--------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| +ProduceResults | 2 | 2 | 0 | c, p | p, c |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| +Filter | 2 | 2 | 26 | c, p, parentNumber | NOT(Contains(SubstringFunction(c.treeNumber,length(parentNumber),None),{ AUTOSTRING1})) AND StartsWith(c.treeNumber,parentNumber) |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| +Apply | 2 | 9 | 0 | p, parentNumber -- c | |
| |\ +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| | +NodeByLabelScan | 9 | 9 | 12 | c | :Node |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| +Projection | 3 | 3 | 3 | parentNumber -- p | p; Add(p.treeNumber,{ AUTOSTRING0}) |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
| +NodeByLabelScan | 3 | 3 | 4 | p | :Node |
+--------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------------------------------------------------+
Total database accesses: 45
But, if we simple add a hint like so
MATCH (p:Node)
WITH p, p.treeNumber + '.' AS parentNumber
MATCH (c:Node)
USING INDEX c:Node(treeNumber)
WHERE c.treeNumber STARTS WITH parentNumber
AND NOT substring(c.treeNumber, length(parentNumber)) CONTAINS '.'
RETURN p, c
it does use the index and we have something like a O(n*log(n)) algorithm (log(n) for the index lookup):
Compiler CYPHER 3.0
Planner COST
Runtime INTERPRETED
+-------------------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+-------------------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| +ProduceResults | 2 | 2 | 0 | c, p | p, c |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| +Filter | 2 | 2 | 6 | c, p, parentNumber | NOT(Contains(SubstringFunction(c.treeNumber,length(parentNumber),None),{ AUTOSTRING1})) |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| +Apply | 2 | 3 | 0 | p, parentNumber -- c | |
| |\ +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| | +NodeUniqueIndexSeekByRange | 9 | 3 | 6 | c | :Node(treeNumber STARTS WITH parentNumber) |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| +Projection | 3 | 3 | 3 | parentNumber -- p | p; Add(p.treeNumber,{ AUTOSTRING0}) |
| | +----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
| +NodeByLabelScan | 3 | 3 | 4 | p | :Node |
+-------------------------------+----------------+------+---------+----------------------+------------------------------------------------------------------------------------------+
Total database accesses: 19
Note that I did cheat a bit when introducing the WITH step creating the prefix earlier, as I noticed it improved the execution plan and DB accesses over
MATCH (p:Node), (c:Node)
USING INDEX c:Node(treeNumber)
WHERE c.treeNumber STARTS WITH p.treeNumber
AND p <> c
AND NOT substring(c.treeNumber, length(p.treeNumber) + 1) CONTAINS '.'
RETURN p, c
which has the following execution plan:
Compiler CYPHER 3.0
Planner RULE
Runtime INTERPRETED
+--------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------+
| Operator | Rows | DB Hits | Variables | Other |
+--------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------+
| +Filter | 2 | 9 | c, p | NOT(p == c) AND NOT(Contains(SubstringFunction(c.treeNumber,Add(length(p.treeNumber),{ AUTOINT0}),None),{ AUTOSTRING1})) |
| | +------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------+
| +SchemaIndex | 6 | 12 | c -- p | PrefixSeekRangeExpression(p.treeNumber); :Node(treeNumber) |
| | +------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------+
| +NodeByLabel | 3 | 4 | p | :Node |
+--------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------+
Total database accesses: 25
Finally, for the record, the execution plan of the original query I wrote (i.e. without the hint) was:
Compiler CYPHER 3.0
Planner COST
Runtime INTERPRETED
+--------------------+----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Operator | Estimated Rows | Rows | DB Hits | Variables | Other |
+--------------------+----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| +ProduceResults | 2 | 2 | 0 | c, p | p, c |
| | +----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| +Filter | 2 | 2 | 21 | c, p | NOT(p == c) AND StartsWith(c.treeNumber,p.treeNumber) AND NOT(Contains(SubstringFunction(c.treeNumber,Add(length(p.treeNumber),{ AUTOINT0}),None),{ AUTOSTRING1})) |
| | +----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| +CartesianProduct | 9 | 9 | 0 | p -- c | |
| |\ +----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| | +NodeByLabelScan | 3 | 9 | 12 | c | :Node |
| | +----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| +NodeByLabelScan | 3 | 3 | 4 | p | :Node |
+--------------------+----------------+------+---------+-----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Total database accesses: 37
It's not the worse one: the one without the hint but with the pre-computed prefix is! This is why you should always measure.
I think we can improve on the query a bit. First, ensure you have either a unique constraint or an index on :Node.treeNumber, as you'll need that to improve your parent node lookups in this query.
Next, let's match on child nodes, excluding root nodes (assuming no .'s in the root's treeNumber) and nodes that have already been processed and have a relationship already.
Then we'll find each node's parent by the treeNumber using our index, and create the relationship. This assumes that a child treeNumber always has 4 more characters, including the dot.
MATCH (child:Node)
WHERE child.treeNumber CONTAINS '.'
AND NOT EXISTS( (child)-[:IS_CHILD_OF]->() )
WITH child, SUBSTRING(child.treeNumber, 0, SIZE(child.treeNumber)-4) as parentNumber
MATCH (parent:Node)
WHERE parent.treeNumber = parentNumber
CREATE UNIQUE (child)-[:IS_CHILD_OF]->(parent)
I think this query avoids a cartesian product as you may get from other answers, and should be around O(n) (someone correct me if I'm wrong).
EDIT
In the event that each subset of numbers in treeNumbers is NOT constrained to 3 (as in your description, actually, with 'A01.111.23'), then you need a different means of deriving the parentNumber. Neo4j is a little weak here, as it lacks both an indexOf() function as well as a join() function to reverse a split(). You may need the APOC Procedures library installed to allow access to a join() function.
The query to handle cases with variable counts of digits in the numeric subsets of treeNumber becomes this:
MATCH (child:Node)
WHERE child.treeNumber CONTAINS '.'
AND NOT EXISTS( (child)-[:IS_CHILD_OF]->() )
WITH child, SPLIT(child.treeNumber, '.') as splitNumber
CALL apoc.text.join(splitNumber[0..-1], '.') YIELD value AS parentNumber
WITH child, parentNumber
MATCH (parent:Node)
WHERE parent.treeNumber = parentNumber
CREATE UNIQUE (child)-[:IS_CHILD_OF]->(parent)
I think I just figured out a solution! (If someone has a more elegant one please do post)
I just realized that the "Tree Number" coding system always uses 3-digit numbers between the dots, i.e. A01.111.230 or C02.100, therefore if a Node is the direct child of another Node, it's "Tree Number" should not only start with the Tree Number of the parent Node, it should also be 4 characters longer (one character for the dot '.' and 3 characters for the numeric value).
Therefore my solution that seems to do the job is:
MATCH (n:Node), (n2:Node)
WHERE (n2.treeNumber STARTS WITH n.treeNumber)
AND (length(n2.treeNumber) = (length(n.treeNumber) + 4))
CREATE UNIQUE (n2)-[:IS_CHILD_OF]->(n);
For your requirement STARTS WITH won't work, since A01.111.23 does indeed start with A01 in addition to starting with A01.111.
The treeNumber is made up of several parts with '.' as the separator. Let's not make any assumptions about the maximum/minimum possible character lengths of the individual parts. What we need is to compare all but the last part of each node's treeNumber with that of the potential child node being tested. You can achieve this using Cypher's split() function as follows:
MATCH (n1:Node), (n2:Node)
WHERE split(n2.treeNumber,'.')[0..-1] = split(n1.treeNumber,'.')
CREATE UNIQUE (n2)-[:IS_CHILD_OF]->(n1);
The split() function splits a string, at each occurrence of a given separator, into a list of strings (parts). In this context the separator is '.' to split any treeNumber. We can select a subset of a list in cypher using the syntax list[{startIndex}..{endIndex}]. Negative indices for reverse lookup are permitted, such ass the one used in the above query.
This solution should generalize to all possible treeNumber values, in the format at hand, irrespective of number of parts and individual part lengths.

All the possible combinations from the decomposition of the elements from an array

For example, if i have this array: {2,3,1} the first element can be decompose in {0,1,2}, the second one in {0,1,2,3} and the third one in {0,1}. So i have to make the sum of every single combination what is possible to be make.
example:
0,1,0
0,0,0
0,3,1
2,3,1
.....
My idea to above this problem is make a kind of tree like this.
0 1 2
| | | | | | | | | | | |
0 1 2 3 0 1 2 3 0 1 2 3
| | | | | | | | | | | | | | | | | | | | | | | |
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
so my idea is make a Recursive function to make the sum:
1) move from top to bottom and when i find the limit change the move.
2) move from left to right, and when i find the limit in the right i return.
3) go back and move to the right, and back to the first step.
This is my code:
void tree(int*A, int i,int n,int j,int mov){
if(mov){ ///move from up to bottom.
if(i==n){ ///n is the large of the array.
return; ///
tree(A,i-1,n,j+1,0);
}
tree(A,i+1,n,j,1);
}
else{ ///move from left to right.
if(j>A[i]){ ///j is decomposition of the element.
return;
}
tree(A,i,n,j+1,0);
}
}
I don't make any sum, I'm just trying to go over all the possible combination. But it's not working. I think is a problem whit what is being returning when the function find a limit.
I really want to solve it by myself but I'm in a dead point right now, maybe a need to know something else about recursive functions, so please don't put a complete solution, i want to learn by my way. I just want tips about what can i do. Is this the best way to solve this problem?
Also, please tell if the problem it's clear, my English is basic so i have problems to express what i want.

Resources