Reputation: 15
quick question again. I'm creating a recursive function that will look for elements in a array of "source" rules and apply those rules to an "target array" of rules if the "source" rule type is the same as the target character. Furthermore the function checks to see if the target character is in an array of symbols or not and adds it if it is not (and throws a few flags on the newly applied rule as well). This is all driven by a recursive call that uses a counter to determine how many iterations have passed and is used to determine the spot in the target array the new rule should be applied, so we don't overwrite.
I've put in a little debugging code to show the results too.
Here's the function itself:
//Recursively tack on any non terminal pointed elements
int recursiveTack(rule * inrule[], char target, rule * targetrule[],
int counter, char symbols[])
{
printf("Got into recursiveTack\n");
printf("target is %c\n", target);
printf("counter is %d", counter);
for (int k = 0; k < sizeof(inrule); k++)
{
if (inrule[k]->type == target)
{
//doublecheck to see if we're trying to overwrite
if (targetrule[counter]->used = true)
{
counter++;
}
targetrule[counter]->head = inrule[k]->head;
targetrule[counter]->type = inrule[k]->type;
targetrule[counter]->used = true;
//Check to see if the elements are new to the symbols table and need to be added
if (!contains(returnGotoChar(targetrule[counter]), symbols))
{
//If not then add the new symbol
addChar(returnGotoChar(targetrule[counter]), symbols);
//Also set the goto status of the rule
targetrule[counter]->needsGoto = true;
//Also set the rule's currentGotoChar
targetrule[counter]->currentGotoChar = returnGotoChar(
targetrule[counter]);
}
counter++;
//recursivly add elements from non terminal nodes
if (isNonTerm(targetrule[counter]))
{
char newTarget = returnGotoChar(targetrule[counter]);
counter = recursiveTack(inrule, newTarget, targetrule, counter,
symbols);
}
}
}
//return how many elements we've added
return counter;
}
Here's the call:
if(isNonTerm(I[i+first][second]))
{
printf("Confirmed non termainal\n");
printf("Second being passed: %d\n", second);
//Adds each nonterminal rule to the rules for the I[i+first] array
second = recursiveTack(I[i], targetSymbol, I[i+first], second, symbols[first]);
}
All the arrays being passed in have been initialized prior to this point. However, the output I get indicates that the recursion is getting killed somewhere before it gets off the ground.
Output:
Second being passed: 0
Confirmed non termainal
Got into recursiveTack
target is E
Segmentation fault
Any help would be great, I've got the rest of the program available too if needs be it's around 700 lines including comments though. I'm pretty sure this is just another case of missing something simple, but let me know what you think.
Upvotes: 0
Views: 123
Reputation: 1582
The biggest thing I see here is:
for(int k = 0; k < sizeof(inrule); k++)
This isn't going to do what you think. inrule is an array of pointers, so sizeof(inrule) is going to be the number of elements * sizeof(rule*). This could very quickly lead to running off the end of your array.
try changing that to:
for (int k = 0; k < sizeof(inrule) / sizeof(rule*); ++k)
Something else you might consider is an fflush(stdout); after your print statements. You're crashing while some output is still buffered so it's likely hiding where your crash is happening.
EDIT:
That won't work. If you had a function that did something like:
int x[10];
for (int i = 0; i < sizeof(x) / sizeof(int); ++i) ...
It would work, but on the other side of the function call, the type degrades to int*, and sizeof(int*) is not the same as sizeof(int[10]). You either need to pass the size, or ... better yet, use vectors instead of arrays.
Upvotes: 0
Reputation: 3511
for(int k = 0; k < sizeof(inrule); k++)
sizeof(inrule)
is going to return the size of a pointer type (4 or 8). Probably not what you want. You need to pass the size of the arrays as parameters as well, if you are going to use these types of structures.
It would be better to use Standard Library containers like std::vector
, though.
Upvotes: 1
Reputation: 1045
if(targetrule[counter]->used = true){
counter++;
}
// what is the guarantee that targetrule[counter] is actually valid? could you do a printf debug before and after it?
Upvotes: 0