I have a problem with too deep recursion in c (I'm using Codeblocks). Around recursion depth of 73000 the message Segmentation fault (core dumped) is occurring. The deepest possible recursion depth is size*size (look at code for size). In my case size=500, so deepest possible recursion is 250000. The function that is run recursively is written below:
void sosedi(int *h, int spin, int k, int l, int rec, gsl_rng * r1){
rec+=1;
if(rec>70000) printf("%d\n",rec);
double tc=2.269185;
double temp = tc*0.5;
*(h+k*size+l)=-*(h+k*size+l);
if(k!=size-2 && *(h+(k+1)*size+l)==spin && pow(2.71828182845904523536, -2*J/temp) < gsl_rng_uniform (r1) ){
sosedi(h,spin,k+1,l,rec,r1);
}
if(k!=1 && *(h+(k-1)*size+l)==spin && pow(2.71828182845904523536, -2*J/temp) < gsl_rng_uniform (r1) ){
sosedi(h,spin,k-1,l,rec,r1);
}
if(l!=size-2 && *(h+k*size+l+1)==spin && pow(2.71828182845904523536, -2*J/temp) < gsl_rng_uniform (r1) ){
sosedi(h,spin,k,l+1,rec,r1);
}
if(l!=1 && *(h+k*size+l-1)==spin && pow(2.71828182845904523536, -2*J/temp) < gsl_rng_uniform (r1) ){
sosedi(h,spin,k,l-1,rec,r1);
}
}
I have been searching for a solution and have come across two solutions. First is to write
--stack="some big number"
in project -> build options -> linker settings -> other linker options, but it doesn't work.
The other option is to use ulimit -s unlimited. I know how to use it in terminal, but don't know how to use this command in codeblocks.
I am not sure recursion depth is causing this error, but the code works for size = 100 and size=200.
Thanks for help.
You appear to be a victim of stack overflow.
You should revisit your code logic and try to use some alternative to avoid or minimize recursion or use some technique similar to tail recursion which is optimized by many compilers.
You may also want to read How to convert a recursive function to use a stack
Ok, I solved the problem. I used setrlimit function. Here
is a very nice description on how to use it.
Related
img of error
Above is an error I have been getting, in relation to this line in my program:
storedData[k] = min(dist[index1][k],dist[index2][k]);
Now here is the surrounding functions to this line:
for(int k = 0; k <arraySize; k++){
if(k!= index1 && k != index2){
if(method == SINGLE_LINKAGE){
storedData[k] = min(dist[index1][k],dist[index2][k]);
} else {
storedData[k] = max(dist[index1][k],dist[index2][k]);
}
}
}
Now after playing around with it for quite a while, I realised that the issue it has is with the incrementing 'k' variable in the for loop. More specifically it is worried that when used as an index in dist, the value returned will be uninitialised. Now in terms of functionality, my program works fine and does everything I want it to do. More notably, I have also initialised this function elsewhere in a helper function which is why this confuses me more. I have initialised all the values from index 0-arraysize which in my head means this should never be an issue. Im not sure if maybe this is caused because its done outside of the main function or something. Regardless it keeps giving me grief and I would like to fix it.
You need to work back from the error to its origin. Even if you are initializing your arrays, it is possible that something is 'uninitializing' them again afterwards. memcheck does not flag uninitialized data when it is copied, only when it affects the outcome.
So in pseudo-code you might have
Array arr;
Scalar uninit; // never initialized
init_array(arr);
// do some stuff
arr[3] = uninit; // no error here
for (i = 1 to arr.size)
store[i] = max(arr[i], arr[i-1]; // errors for i == 3 and 4
There are two things that you could try. Firstly, try some 'printf' debugging, something like
for(int k = 0; k <arraySize; k++) {
if(k!= index1 && k != index2) {
fprintf(stderr, "DEBUG: k %d index1 %d index2 %d\n", k, index1, index2);
// as before
Then run Valgrind without a log file. You should then be able to see which indices cause the error(s).
Next, try using ggbserver. Run valgrind in one terminal with
valgrind --vgdb-error=0 prog args
and then run gdb in a second terminal to attach (see the text that is output in the 1st terminal for the commands to use).
You can then use gdb as usual (except no 'run') to control your guest app, with the additional ability to run valgrind monitor commands.
I have made a program to a board game. My problem is a function, so that certain fields transport the player back or forward. Apparently the thing I did doesn't work.
int numbers()
{
int maxscore;
int numbers[10];
maxscore = enter();
srand(time(NULL));
int nonumbers[3] = {0, 1, maxscore}; //to initialize the scores there shouldn't be a badfield
numbers[10] = rand() % maxscore + 1;
if(numbers[10] == nonumbers[3])
{
numbers[10] = rand() % maxscore + 1;
}
return numbers;
}
int badfields = numbers();
if(score[i] == badfields)
{
printf("Player %d. goes 5 fields backwards", playershown);
score[i] = score[i] - 5;
printf("This player is now in %d Field", score[i]);
}
Somehow I have to repeat the process of entering the maximum score.
I won't directly answer the "question" because there is no "question" to be answered. As others have pointed out in the comments, you need to be more specific and provide a proper description of your problem. But I can still provide the following feedback:
It seems to me you don't quite understand arrays and their indexing. For example, this line should give you a segmentation fault error, or at the very least make a comparison with an unknown value:
if(numbers[10] == nonumbers[3])
This is because your nonumbers array has 3 elements, and thus they should be addressed as nonumbers[0], nonumbers[1] or nonumbers[2] (or, in general, as Weather Vane put it in the comments, from nonumbers[0] to nonumbers[array_lenght-1]). nonumbers[3] will access an undefined position in memory. Your problem could be related to this.
Note that neither me nor anybody is going to review your entire code
to find the error. As stated above, please be more specific.
Also, are you sure you got rid of all compiler errors? Because further down your code you have an uninitialized variable i. To be sure you got rid of all potentially nasty errors, open the terminal (I'm assuming you are on linux) and use the following command to compile your program:
gcc *.c -Wall -Wextra -o program
Then run it with:
./program
I am kinda new to C and I am trying to write a simple snake remake.
You can view the source on github: https://github.com/blackwolf12333/Snake
When building there are no warnings or errors in the output. But when I run the executable and hit enter it exit's with "Segmentation fault(core dumped)".
I am not a pro yet with pointers, I come from java, and when googling I found that it probably is a problem with pointers.
I have no idea of where it is going wrong because for as far as I know I am doing things right. The problem is when I try to loop through my snake's body_part's.
void print_snake() {
int i;
body_part *next = main_snake.head.next;
move(main_snake.head.pos.x, main_snake.head.pos.y);
addch('$');
for(i = 0; i < main_snake.length; i++) { //TODO: segfaults when 'main_snake.length'(should be this) instead of 'main_snake.length - 1'
printf("1 part");
print_body_part(next);
next = next->next;
}
}
That's from the snake.c file in the repository.
I hope you guys can help me,
greetings blackwolf12333
Before going deep through the code it is obvious that when next becomes null and next->next causes segmentation fault.
In the loop you are starting at a node next to head(main_snake.head.next). Therefore in a list of 4 objects you are processing only 3 objects. In that case iterations should be 3 instead of 4 because main_snake.length counts the head also as shown in the function initialize_snake. That is why you are getting segmentation fault.
If you want to iterate over a chained list, don't use a seperate stop condition. Your i variable and main_snake.length are not necessary. You can replace
for(i = 0; i < main_snake.length; i++)
with
body_part *next;
for(next = main_snake.head.next; next->next != NULL; next=next->next){
...
}
We are using Blodshed Dev-C++ to in an image processing project. We are implementing connected component labelling on a video frame. We have to use a recursive function which recurses so many times that we get a stackoverflow. How can we have a larger stack size? Is it possible to change it through some linker parameters or anything similar?
void componentLabel(int i,int j,IplImage *img){
// blueFrame = img->imageData[i*3*width+j*3];
// greenFrame = img->imageData[i*3*width+j*3+1];
// redFrame = img->imageData[i*3*width+j*3+2];
if(!( img->imageData[i*3*width+j*3]==0 && img->imageData[i*3*width+j*3+1]==0 && img->imageData[i*3*width+j*3+2]==0 ) ){
//printf("iffffff aq\n");
return;
}
else{
//printf("else aq %d\n",sayac_label);
img->imageData[i*3*width+j*3]=1;
new_object.pixel_count=new_object.pixel_count+1;
new_object.total_row=new_object.total_row+i;
new_object.total_col=new_object.total_col+j;
if(j<width-1 ){
componentLabel(i,j+1,img);
}
if(j>0 ){
componentLabel(i,j-1,img);
}
if(i<height-1 ){
if(i>new_object.bottom.satir){
new_object.bottom.satir=i;
new_object.bottom.sutun=j;
}
componentLabel(i+1,j,img);
}
if(i>0 ){
if(i<new_object.top.satir){
new_object.top.satir=i;
new_object.top.sutun=j;
}
return componentLabel(i-1,j,img);
}
}
Only one approach will guarantee that you won't run out of stack size - reformulate the algorithm to be tail recursive (and ensure that your compiler is optimizing tail calls - usually an -O3 (or -O2?) optimization flag).
Short of that, have you increased the maximum stack size that the shell will grant your task?
ulimit -s <maximum stack size>
I had an earlier question about integrating Mathematica with functions written in C++.
This is a follow-up question:
If the computation takes too long I'd like to be able to abort it using Evaluation > Abort Evaluation. Which of the technologies suggested in the answers make it possible to have an interruptible C-based extension function? How can "interruptibility" be implemented on the C side?
I need to make my function interruptible in a way which will corrupt neither it, nor the Mathematica kernel (i.e. it should be possible to call the function again from Mathematica after it has been interrupted)
For MathLink - based functions, you will have to do two things (On Windows): use MLAbort to check for aborts, and call MLCallYieldFunction, to yield the processor temporarily. Both are described in the MathLink tutorial by Todd Gayley from way back, available here.
Using the bits from my previous answer, here is an example code to compute the prime numbers (in an inefficient manner, but this is what we need here for an illustration):
code =
"
#include <stdlib.h>
extern void primes(int n);
static void yield(){
MLCallYieldFunction(
MLYieldFunction(stdlink),
stdlink,
(MLYieldParameters)0 );
}
static void abort(){
MLPutFunction(stdlink,\" Abort \",0);
}
void primes(int n){
int i = 0, j=0,prime = 1, *d = (int *)malloc(n*sizeof(int)),ctr = 0;
if(!d) {
abort();
return;
}
for(i=2;!MLAbort && i<=n;i++){
j=2;
prime = 1;
while (!MLAbort && j*j <=i){
if(i % j == 0){
prime = 0;
break;
}
j++;
}
if(prime) d[ctr++] = i;
yield();
}
if(MLAbort){
abort();
goto R1;
}
MLPutFunction(stdlink,\"List\",ctr);
for(i=0; !MLAbort && i < ctr; i++ ){
MLPutInteger(stdlink,d[i]);
yield();
}
if(MLAbort) abort();
R1: free(d);
}
";
and the template:
template =
"
void primes P((int ));
:Begin:
:Function: primes
:Pattern: primes[n_Integer]
:Arguments: { n }
:ArgumentTypes: { Integer }
:ReturnType: Manual
:End:
";
Here is the code to create the program (taken from the previous answer, slightly modified):
Needs["CCompilerDriver`"];
fullCCode = makeMLinkCodeF[code];
projectDir = "C:\\Temp\\MLProject1";
If[! FileExistsQ[projectDir], CreateDirectory[projectDir]]
pname = "primes";
files = MapThread[
Export[FileNameJoin[{projectDir, pname <> #2}], #1,
"String"] &, {{fullCCode, template}, {".c", ".tm"}}];
Now, here we create it:
In[461]:= exe=CreateExecutable[files,pname];
Install[exe]
Out[462]= LinkObject["C:\Users\Archie\AppData\Roaming\Mathematica\SystemFiles\LibraryResources\
Windows-x86-64\primes.exe",161,10]
and use it:
In[464]:= primes[20]
Out[464]= {2,3,5,7,11,13,17,19}
In[465]:= primes[10000000]
Out[465]= $Aborted
In the latter case, I used Alt+"." to abort the computation. Note that this won't work correctly if you do not include a call to yield.
The general ideology is that you have to check for MLAbort and call MLCallYieldFunction for every expensive computation, such as large loops etc. Perhaps, doing that for inner loops like I did above is an overkill though. One thing you could try doing is to factor the boilerplate code away by using the C preprocessor (macros).
Without ever having tried it, it looks like the Expression Packet functionality might work in this way - if your C code goes back and asks mathematica for some more work to do periodically, then hopefully aborting execution on the mathematica side will tell the C code that there is no more work to do.
If you are using LibraryLink to link external C code to the Mathematica kernel, you can use the Library callback function AbortQ to check if an abort is in progress.