Stack frame size of a function - c

Simple question: Is there a way to determine the stack size of a function?
int stackframe_size(int run) {
int i ;
if(!run) {
return ((int)(&i) - stackframe_size(++run));
}
return (int)(&i);
}
int main() {
int x, y;
double d;
char c;
int a = 4;
int b = 5;
int we = 6;
int e = 123123;
int hmm = 34453;
int lol = 45;
int asd = 23;
x = 1;
y = g(x);
d = f(x, y, x-y);
c = 'a';
printf("%d", stackframe_size(0));
}
I am running the function I obtained from another thread to find the call stack size and it always seems to return 48...is there another way to find out or is this the only way?

Related

about remove/replace struct

I have a C language code that uses struct, including functions and function calls that initialize the structure. Now I want to remove the use of structs. Due to problems with code execution, and a lot of code and complicated structs, I can't change these manually. Functions and structures, so I have to find an automated method. The following code is a simple example.
Is there any better way or idea?
#include<stdio.h>
struct A
{
int a;
int b;
};
struct A add(int x, int y)
{
struct A t;
t.a = x + y;
return t;
}
int main()
{
struct A t = add(3, 4);
printf("t.a = %ld\n", t.a);
return 0;
}
To:
#include<stdio.h>
int main()
{
int A_a = 3;
int A_b = 4;
int A_a_b = A_a + A_b;
printf("%d\n", A_a_b);
return 0;
}
Have you tried antlr?
I guess you'd like refactor the code to below.
include
/*
struct A
{
int a;
int b;
};
*/
/*
struct A add(int x, int y)
{
struct A t;
t.a = x + y;
return t;
}
*/
int main()
{
/*
struct A t = add(3, 4);
*/
int A0_t_a; //t.a
int A0_t_b; //t.b
{
//add(3, 4)
int x = 3;
int y = 4;
//struct A t;
int A1_t_a;
int A1_t_b;
//t.a = x + y
A1_t_a = x + y;
//return t
A0_t_a = A1_t_a;
A0_t_b = A1_t_b;
}
/*
printf("t.a = %ld\n", t.a);
*/
printf("t.a = %ld\n", A0_t_a);
return 0;
}

Is there a best practice for allocating memory in C?

I've been trying to make a function that appends matrix B onto Matrix A by making a new combined matrix. The first function I created passes a pointer (that was declared in main()) to the function which then works up the pointer to add values. This worked. However, I am also trying a different method by using malloc() within the function to define a pointer so that the function is more portable and dyanmic. However, when I try to print the final values in the final matrix I am getting undefined behavior.
Here is the included function from the created header file.
#include <stdio.h>
#include <stdlib.h>
int *fAddArrays(int *A, int *B, int a, int b)
{
int *O;
O = (int *) malloc((a+b) * sizeof(int));
int c;
int d;
for (c = 0; c < a; c++)
{
*O = *A;
A++;
O++;
}
for (d = 0; d < b; d++)
{
*O = *B;
B++;
O++;
}
return O;
}
Here is the use of the function in main()
#include <stdio.h>
#include <unistd.h>
#include "CustomArray.h"
#include <stdlib.h>
int main(void)
{
int A[5] = {1,2,3,4,5};
int B[7] = {6,7,8,9,10,11,12};
int a = 5;
int b = 7;
int c = a + b;
int x = 0;
int NewArray[c], *ArrayPtr;
ArrayPtr = fAddArrays(A,B,a,b);
for( x = 0; x < c; x++)
{
*(NewArray + x) = *ArrayPtr;
printf("Value of NewArray[%d] = %d\n", x, *ArrayPtr);
sleep(1);
ArrayPtr++;
}
return 0;
}
Your problem is that you increment O and then return it.
You need to save away the original value and increment a copy.
int *fAddArrays(int *A, int *B, int a, int b) {
int * original = (int *) malloc((a+b) * sizeof(int));
int * p = original;
for (int c = 0; c < a; c++) {
*p = *A;
A++;
p++;
}
for (int d = 0; d < b; d++) {
*p = *B;
B++;
p++;
}
return original;
}

how to optimize repetitive addition

#define NULL 0
int main()
{
int *array1=NULL,*array2=NULL;
int x =add(array1[0],array2[0]);
int y =add(array1[1],array2[7]);
int x =add(array1[2],array2[3]);
int y =add(array1[3],array2[4]);
int x =add(array1[4],array2[6]);
int y =add(array1[5],array2[1]);
int x =add(array1[6],array2[5]);
int y =add(array1[7],array2[2]);
................
................
int x =add(array1[252],array2[0]);
int y =add(array1[253],array2[7]);
int x =add(array1[254],array2[3]);
int y =add(array1[255],array2[4]);
}
Basically index for array1 is incrementing by 1 starting from 0 to till 255
but the index for array2 is fixed from 0 to 7. So I want to optimize this multiple addition. How to optimize this?
what you can is
int j = 0,order[] = {0,7,3,4,6,1,5,2};
for(int i = 0;i <256; i +=2)
{
int x =add(array1[i],array2[order[j%8]]);
j++;
int y =add(array1[i+1],array2[order[j%8]]);
j++;
}
UPDATE
alternate solution can be (if you want without using i+=2)
int j = 0,order[] = {0,7,3,4,6,1,5,2};
for(int i = 0;i <256; i ++)
{
int x =add(array1[i],array2[order[j%8]]);
j++;
i++;
if(i>=256) break; //Improves it if you have non even condition
int y =add(array1[i],array2[order[j%8]]);
j++;
}
edit by sam
Now i want to compare this two values of x and y and selecting value based on comparision
CurrentTre=256;
if (x > y)
{
*array3[0]= x;
*array4[CurrentTre +0] = 0;
}
else
{
*array3[i] = y;
*array4[CurrentTre + 0] = 1;
}
..........
..........
if (x > y)
{
*array3[0]= x;
*array4[CurrentTre +127] = 254;
}
else
{
*array3[i] = y;
*array4[CurrentTre + 127] = 255;
}
/////////////
my approach is this way
if (x > y)
{
*array3[i]= x;
*array4[int CurrentTre +i] = int number[i]<<1;
}
else
{
array3[i] = y;
array4[int CurrentTre + i] = int number[i]<<1|1;
}
} //end function main
I want to optimize the code my optimization is given below
please check whether am i doing right or not..?
uint32 even_number[255] ={0};
uint32 loop_index1=0;
uint32 loop_index2=0;
uint16 order[256]={0,7,3,4,6,1,5,2,4,3,7,0,1,6,2,5,7,0,4,3,2,5,1,6,3,4,0
,7,6,1,5,2,4,3,7,0,1,6,2,5,0,7,3,4,5,2,6,1,3,4,0,7,6,1,5,2,7,0,4,3,2,5
,1,6,5,2,6,1,0,7,3,4,1,6,2,5,4,3,7,0,2,5,1,6,7,0,4,3,6,1,5,2,3,4,0,7,1
,6,2,5,4,3,7,0,5,2,6,1,0,7,3,4,6,1,5,2,3,4,0,7,2,5,1,6,7,0,4,3,3,4,0,7
,6,1,5,2,7,0,4,3,2,5,1,6,4,3,7,0,1,6,2,5,0,7,3,4,5,2,6,1,7,0,4,3,2,5,1
,6,3,4,0,7,6,1,5,2,0,7,3,4,5,2,6,1,4,3,7,0,1,6,2,5,6,1,5,2,3,4,0,7,2,5
,1,6,7,0,4,3,1,6,2,5,4,3,7,0,5,2,6,1,0,7,3,4,2,5,1,6,7,0,4,3,6,1,5,2,3
,4,0,7,5,2,6,1,0,7,3,4,1,6,2,5,4,3,7,0}; //all 256 values
for(loop_index1;loop_index1<256;loop_index1++)
{
m0= (CurrentState[loop_index1]+Branch[order[loop_index2]]);
loop_index2++;
loop_index1++;
if(loop_index1>=256)
break;
m1= (CurrentState[loop_index1]+Branch[order[loop_index2]]);
loop_index2++;
if (mo > m1)
{
NextState[loop_index1]= m0;
SurvivorState[CurrentTrellis + loop_index1] =
even_number[loop_index1]<<1;
}
else
{
NextState[loop_index1] = StateMetric1;
SurvivorState[CurrentTrellis + loop_index1] =
even_number[loop_index1<<1|1;
}
}
first step:
for (int i = 0; i < 256; i+=8) {
x = add(array1[i], array2[0]);
y = add(array1[i+1], array2[7]);
...
}
Use a pointer
int *array1 = NULL, *array2 = NULL;
int *ptr1 = array1;
int x = add(*ptr1++, array2[0]);
int y = add(*ptr1++, array2[7]);
int x = add(*ptr1++, array2[3]);
int y = add(*ptr1++, array2[4]);
int x = add(*ptr1++, array2[6]);
int y = add(*ptr1++, array2[1]);
int x = add(*ptr1++, array2[5]);
int y = add(*ptr1++, array2[2]);
................
................
int x = add(*ptr1++, array2[0]);
int y = add(*ptr1++, array2[7]);
int x = add(*ptr1++, array2[3]);
int y = add(*ptr1++, array2[4]);
But remember premature optimization is the root of all evil.
Before optimizing measure and make certain you need optimizing the accesses to the array.
After optimizing measure to make certain the optimization had any effect.

How do we use structs?

The main problem I'm having is having so many parameters, which I just want to get rid of, and yes I do not understand the logic of structs. However, it is becoming a bit more clear...
EDIT
So cHao wanted me to use a specific case so here is an example I cooked up:
#include <stdio.h>
int main()
{
//Top coord. of the square
int top_x1 = 0;
int top_y1 = 10;
int top_x2 = 10;
int top_y2 = 10;
//Bottom coord. of the square
int bottom_x1 = 0;
int bottom_y1 = 0;
int bottom_x2 = 10;
int bottom_y2 = 0;
//Left coord. of the square
int left_x1 = 0;
int left_y1 = 0;
int left_x2 = 0;
int left_y2 = 10;
//Right coord. of the square
int right_x1 = 10;
int right_y1 = 0;
int right_x2 = 10;
int right_y2 = 10;
parameter(top_x1, top_y1, top_x2, top_y2, bottom_x1,
bottom_y1, bottom_x2, bottom_y2, left_x1,
left_y1, left_x2, left_y2, right_x1, right_y1,
right_x2, right_y2);
}
parameter (int top_x1,int top_y1,int top_x2,int top_y2,int bottom_x1,
int bottom_y1,int bottom_x2,int bottom_y2,int left_x1,
int left_y1,int left_x2,int left_y2,int right_x1,int right_y1,
int right_x2,int right_y2)
{
int totalParameter, topSide, bottomSide, leftSide, rightSide;
topSide = (top_x2 - top_x1);
bottomSide = (bottom_x2 - bottom_x1);
leftSide = (left_y2 - left_y1);
rightSide = (right_y2 - right_y1);
totalParameter = (topSide + bottomSide + leftSide + rightSide);
printf("%d\n", totalParameter);
}
and if I try using structs...
#include <stdio.h>>
struct coordinates
{
int x1, y1, x2, y2;
};
int main()
{
struct coordinates top;
struct coordinates bottom;
struct coordinates left;
struct coordinated right;
//Top line of the square
top.x1 = 0;
top.y1 = 10;
top.x2 = 10;
top.y2 = 10;
//Bottom line of the square
bottom.x1 = 0;
bottom.y1 = 0;
bottom.x2 = 10;
bottom.y2 = 0;
//Left line of the square
left.x1 = 0;
left.y1 = 0;
left.x2 = 0;
left.y2 = 10;
//Right line of the square
right.x1 = 10;
right.y1 = 0;
right.x2 = 10;
right.y2 = 10;
}
parameter(top, bottom, left, right)
{
int totalParameter, topSide, bottomSide, leftSide, rightSide;
topSide = (top.x2 - top.x1);
bottomSide = (bottom.x2 - bottom.x1);
leftSide = (left.y2 - left.y1);
rightSide = (right.y2 - right.y1);
totalParameter = topSide + bottomSide + leftSide + rightSide;
printf("%d\n", totalParameter);
}
Doesn't work though, any help? :P
Error I get is: "Request for member 'x1' in something not a structure of union.
For all the x and y coords.
typedef struct _foo
{
int x1, x2, x3,..., x20;
} foo;
int add(const foo *pBar)
{
return pBar->x1 + pBar->x2 + pBar->x3 + ... + pBar->x20;
}
int main()
{
// declare and initialize the struct
foo bar = { 1, 2, 3, ..., 20 };
// an alternative way of initializing the struct:
bar.x1 = 1;
bar.x2 = 2;
bar.x3 = 3;
:
bar.x20 = 20;
int total = add(&bar);
}
Refers to general using of struct, not the technical side: (because it seems to me that you do not understand the logic in it)
You should use struct for group of variables they part of one thing.
For example, struct point (to represent point in in space) will contain int for X and int for Y.
You should use array for group of variables they the relation between their is serial.
For example: students in class, since you want to do same actions on each student in sequence.

segmentation fault

I am trying get a mandelbrot image clearly with the sequential programming in C++, but I am getting a segmentation fault during runtime. I have no idea about the seg. fault, but my program is perfectly compiling with no errors.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int file_write(unsigned int width, unsigned int height)
{
unsigned int **color = NULL;
FILE *fractal = fopen("mandelbrot_imageSequential.ppm","w+");
if(fractal != NULL)
{
fprintf(fractal,"P6\n");
fprintf(fractal,"# %s\n", "Mandelbrot_imageSequential.ppm");
fprintf(fractal,"%d %d\n", height, width);
fprintf(fractal,"40\n");
int x = 0, y = 0;
unsigned int R = 0, G = 0, B = 0;
for(x = 0; x < width; ++x)
{
for(y = 0; y < height; ++y)
{
R = (color[y][x]*10);
G = 255-((color[y][x]*10));
B = ((color[y][x]*10)-150);
if(R == 10)
R = 11;
if(G == 10)
G = 11;
if(B == 10)
B = 11;
putc(R, fractal);
putc(G, fractal);
putc(B, fractal);
}
}
fclose(fractal);
}
return 0;
}
int method(int x, int y, int height, int width, double min_re, double max_re, double min_im, double max_im, int max_iterations)
{
double threshold = 4;
double x_factor = (max_re-min_re)/(width-1);
double y_factor = (max_im-min_im)/(height-1);
double c_im = max_im - y*y_factor;
double c_re = min_re + x*x_factor;
double Z_re = c_re, Z_im = c_im;
unsigned int col = 0;
for(unsigned n = 0; n < max_iterations; ++n)
{
double Z_re2 = Z_re*Z_re, Z_im2 = Z_im*Z_im;
if(Z_re2 + Z_im2 > threshold)
{
col = n;
break;
}
Z_im = 2 * Z_re * Z_im + c_im;
Z_re = Z_re2 - Z_im2 + c_re;
}
return col;
}
int main(int argc, char *argv[])
{
unsigned int width;
unsigned int height;
unsigned int max_iterations;
unsigned int **color = NULL;
int x,y;
double threshold;
double min_re;
double max_re;
double min_im;
double max_im;
unsigned int NUM_OF_THREADS;
if(argc != 10)
{
printf("There is an error in the input given.\n");
return 0;
}
else
{
height = atoi(argv[1]);
width = atoi(argv[2]);
max_iterations = atoi(argv[3]);
min_re = atof(argv[4]);
max_re = atof(argv[5]);
min_im = atof(argv[6]);
max_im = atof(argv[7]);
threshold = atoi(argv[8]);
NUM_OF_THREADS = atoi(argv[9]);
}
color = (unsigned int**)malloc(height*sizeof(unsigned int*));
printf("height = %d\twidth = %d\tmaximum_iterations = %d\tminimum_x-value = %.2f\tmaximum_x-value = %.2f\tminimum_y-value = %.2f\tmaximum_y-value = %.2f\tthreshold_value = %.2f\tno. of threads = %d\t\n",height,width,max_iterations,min_re,max_re,min_im,max_im,threshold,NUM_OF_THREADS);
for(x = 0; x < height; x++)
{
color[x] = (unsigned int*)malloc(width*sizeof(unsigned int));
}
time_t ts,te;
time(&ts);
method(x,y,height,width,min_re,max_re,min_im,max_im,max_iterations);
time(&te);
double diff = difftime(te,ts);
file_write(width, height);
printf("Total Time elapsed: %f\n",diff);
return 0;
}
How to correct this segmentation fault?
At least one problem is in the file_write function.
unsigned int **color = NULL;
R = (color[y][x]*10);
I assume the color should be an input parameter.
If you are on Linux machine do the following :
$ulimit -c unlimited
Then run the code. Notice a core.[pid] file is generated. fire up gdb like following
$gdb ./your_app core.[pid]
It will take you the statement where segfault occurred. issue a "backtrace" command in gdb prompt to see the call hierarchy.
Remember compiling with "-g" flag to get more verbose gdb output.
There are two major problems with your code:
You allocate memory for the color array but then use a different color inside file_write() which is initialized to NULL.
You need to pass the first color as an argument to file_write():
int main(...)
{
...
file_write(color, width, height);
printf("Total Time elapsed: %f\n",diff);
return 0;
}
And declare the other color as an argument to file_write():
int file_write(unsigned int **color, unsigned int width, unsigned int height)
{
/* unsigned int **color = NULL; // Removed */
...
You're only calling method() once and not storing anything into color. You need to call it in a loop. Something similar to:
/* Untested */
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
color[y][x] = method(x,y,height,width,min_re,max_re,min_im,max_im,max_iterations);
}
}
Then, of course, you should check the return values of malloc(), fopen(), fprintf(), fclose(), ... , and check that the input variables have reasonable values and so on.
I also noticed that you're passing width and height in different order to file_write() and method(). To avoid future headaches, I would change the method() function to method(x, y, width, height) so that the horizontal and vertical arguments are passed in the same order.

Resources