What does the flag -O2 means ?, because I get the signal SIGSEGV
when I compile my program with the flag -O2
, but If I remove that flag at the gcc
command, the program works perfectly without any error, I was trying to solve Primitive Calculator
problem using recursive functions, it's just a recursion and Memoization problem.
then with this command the program works perfectly...
gcc -pipe -std=c11 -g file.c
But with this another command it doesn't works, gets the signal SIGSEGV ... :'(
gcc -pipe -O2 -std=c11 -g file.c
For example If run the program compiled with that flag(-O2
), with the input 96234
, I get this error.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/windowsky/Desktop/coursera/week5/a.out
96234
Program received signal SIGSEGV, Segmentation fault.
0x00005555555551b2 in options (num=num@entry=21355, ptr=ptr@entry=0x7fffffffe7a8) at eje2.c:26
26
(gdb)
It crashes with any reason in that point, as I mention before if you remove the flag -O2
the program works perfectly, I just want to know what the -O2
flag means at the compiler, because this doesn't make any sense for me I'm going to lose my head.
Then this is the code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdbool.h>
/* this is the type of operations that we can do */
enum opeType {
SUB_1,
DIV_2,
DIV_3
};
/* options: Recursive options */
int options (int num, int **ptr)
{
int minOperations, numOperations, i;
if (num <= 1)
return 0;
numOperations = 0;
minOperations= 2147483647;
for (i = 0; i < 3; ++i) {
switch (i) {
case DIV_2:
if (num % 2 == 0) {
if (*(*ptr + (num / 2)) == 0)
*(*ptr + (num / 2)) = options(num / 2, ptr) + 1;
numOperations = *(*ptr + (num / 2));
}
break;
case DIV_3:
if (num % 3 == 0) {
if (*(*ptr + (num / 3)) == 0)
*(*ptr + (num / 3)) = options(num / 3, ptr) + 1;
numOperations = *(*ptr + (num / 3));
}
break;
case SUB_1:
if (*(*ptr + (num -1)) == 0)
*(*ptr + (num - 1)) = options(num - 1, ptr) + 1;
numOperations = *(*ptr + (num - 1));
break;
}
if (numOperations < minOperations && numOperations != 0)
minOperations = numOperations;
}
return minOperations;
}
/* findingPath: This is the function that is going to find the path */
bool findingPath (int **ptr2, int num, int c)
{
int i;
bool flag;
if (num == 1)
return true;
else if (c >= 0) {
flag = false;
for (i = 2; i > -1; --i) {
switch (i) {
case SUB_1:
if (flag = findingPath(ptr2, num - 1, c - 1))
*(*ptr2 + c) = num - 1;
break;
case DIV_2:
if (num % 2 == 0 && (flag = findingPath(ptr2, num / 2, c - 1)))
*(*ptr2 + c) = num / 2;
break;
case DIV_3:
if (num % 3 == 0 && (flag = findingPath(ptr2, num / 3, c - 1)))
*(*ptr2 + c) = num / 3;
break;
}
if (flag)
return true;
}
}
return false;
}
/* one_test: Just one test */
void one_test ()
{
int num, *ptr, *ptr2;
int res, i;
num = 6;
ptr = (int *) malloc(sizeof(int) * (num + 1));
memset(ptr, 0, num);
res = options(num, &ptr);
assert(res == 2);
ptr2 = (int *) malloc(sizeof(int) * (res > 0 ? res : 1));
memset(ptr2, 0, res > 0 ? (res - 1) : 1);
findingPath(&ptr2, num, res > 0 ? (res - 1) : 1);
printf("%i\n", res);
for (i = 0; i < res; i++)
printf("%i ", *(ptr2 + i));
printf("%i ", num);
free(ptr);
free(ptr2);
ptr = NULL;
ptr2 = NULL;
}
/* manual_test: This is the manual test */
void manual_test ()
{
int num, *ptr, *ptr2;
int res, i;
scanf("%i", &num);
ptr = (int *) malloc(sizeof(int) * (num + 1));
memset(ptr, 0, num);
res = options(num, &ptr);
ptr2 = (int *) malloc(sizeof(int) * (res > 0 ? res : 1));
memset(ptr2, 0, res > 0 ? (res - 1) : 1);
findingPath(&ptr2, num, res > 0 ? (res - 1) : 1);
printf("%i\n", res);
for (i = 0; i < res; i++)
printf("%i ", *(ptr2 + i));
printf("%i ", num);
free(ptr);
free(ptr2);
ptr = NULL;
ptr2 = NULL;
}
void main ()
{
//one_test();
manual_test();
}