segment violation error on function call - c

I have a written a C program to find the k nearest neighbors of all the points in a given set of points (randomly generated). The problem is when I increase the number of points(and consequently the array size) to 10000 the program gives segment violation error as soon as I call the function to find out the nearest neighbors. I am not able to get inside the function using the debugger. As soon as I do a "Step Into" the program crashes.
I have used code-blocks and Eclipse CDT (on Windows 7) and both give the error at the same point. In case of code-blocks it gives segment violation and in case of Eclipse it first shows - "No source available for __chkstk_ms() at 0x4039a7" and then the error comes from the OS itself - "KNN.exe has stopped working"
However the program runs fine on Linux(Ubuntu 32bit).
Here is the code snippet :
#define MAX_SIZE 10000
int main()
{
int n = MAX_SIZE;
int k = 3;
int i;
double points[MAX_SIZE*2]; //2-D array in row-major order
double result[MAX_SIZE*3*2];
srand(time(NULL));
for(i=0; i < n; i++)
{
points[i*2] = (double)rand()/(double)RAND_MAX;
points[i*2 + 1] = (double)rand()/(double)RAND_MAX;
}
seek(points,n,k,result); //<---------- ERROR
seek(points,n,k,result); //<------------ NO ERROR
....
}
void seek(const double * const points, int n, int k, double *result)
{
TreeNode qtree[MAX_SIZE];
int order_array[MAX_SIZE];
int num_nodes = build_quadtree(a, n, k, qtree,order_array);
......
}
struct tree_node
{
int id;
int num_points;
int start_order;
int end_order;
int parent;
int child[4];
struct rectangle rect;
enum boolean is_leaf;
};
struct point
{
double x;
double y;
};
struct rectangle
{
int id;
double xmin,xmax,ymin, ymax;
struct point midpt;
};
What is more confusing is that I have another function with the same arguments which is running without any problem.
Please provide suggestions on how to debug this.
EDIT:- . I have posted the first few lines of seek() function. As the replies have pointed out I am actually allocating a lot of memory on the seek function but I am wondering why it is not a problem in linux.

I think you're exceeding your available stack (see the MSDN docs on _chkstk). Try allocating the arrays dynamically instead
int main()
{
double* points = malloc(sizeof(double) * MAX_SIZE*2];
double* result = malloc(sizeof(double) * MAX_SIZE*3*2];
...
free(points);
free(result);
}
The stack overflow is happening when you call seek. You haven't posted code for it but may have to rework it also to reduce its stack use.

Perhaps following code is the real culprit. both qtree and orderarray are also stack allocated. I would change the MAX_SIZE to a lower value and see the issue re-proes.
TreeNode qtree[MAX_SIZE];
int order_array[MAX_SIZE];

Related

How to Generalize functions in C

I'm writing some Code that does some basic analysis on data.
The data collected is in an array of structs. It takes the approximate form:
struct page {
int width;
int length;
char name[50];
// etc...
}
struct page pages[100];
I need to write code that finds the smallest width, largest width, smallest length, largest length, etc. So I write code that looks something like this:
int smallestWidth(struct page pages[]){
unsigned int smallest = -1;
(for loop){
if (smallest > pages[i].width) smallest = pages[i].width;
}
return smallest;
}
And then I find that I'm copy-pasting this function and changing tiny details for the other requirements like largest width. And whenever I'm copy-pasting chunks of code, that raises alarm bells for me, and I'm thinking I'm doing it wrong.
But, I'm kind of new to C, so I'm not sure what the right way to approach this is.
How would you write this in C properly (if there is a proper way) that minimizes the amount of code that I'm copy-pasting?
C++ language has overrides and pointer to members that C has not. So the C way would be to use auxilliary functions to extract the correct data and compare them:
int getLength(struct page *page) {
return page->length;
}
int getWidth(struct page *page) {
return page->width;
}
int lesser(int a, int b) {
return a<b;
}
int greater(int a, int b) {
return a>b;
}
typedef int(*extractor)(struct page *p);
typedef int (*comparator)(int a, int b);
int process(struct page * p, int size, extractor ext, comparator cmp) {
// code here the generic part
...
}
int lesserWidth = process(pages, 100, &getWidth, &lesser);
...
But it includes a good deal of boiler plate code, so it may be interesting or not depending on the complexity of the generic part...
I think the following will be classified as a Horrible Hack, however, it satisfies your request. It only works for integers because of the compare.
struct page {
int width;
int length;
// etc...
} pages[100] = {{1,2},{3,4},{5,6}};
int smallestX(struct page pages[], size_t offset)
{
unsigned int smallest = -1, k;
for (int i=0; i<3; i++){
k= *((int *)((char *)(&pages[i])+offset));
if (smallest > k) smallest = k;
}
return smallest;
}
void example(void)
{
printf ("smallest width= %d\n", smallestX(pages, offsetof(struct page, width)));
printf ("smallest length= %d\n", smallestX(pages, offsetof(struct page, length)));
}
Clarification:
It uses the offsetof macro to get the offset of the member from the beginning of the struct. In the function, it now takes the address of the ith element of the array, interprets that as a byte address, adds the offset (which is in bytes), interprets that as a pointer to an int, dereferences that int and uses it in the compare.
Note: it is possible to extend this method to compare any item by providing a compare function as parameter.

Multiple files and structs, differing outputs

In this small program, all three files all have different responsibilities.
The goal of the program is to read data from the data.c file into the struct array created in testing.h, which can be then accessed and used in testing.c.
What I am finding is that when I attempt to print outside the local scope and furthermore attempt to print outside the file the output changes.
data.c
void data() {
size_t friends[] = {1,3,4};
userdata[0].friends_ids = friends;
size_t friends2[] = {5,8,9};
userdata[1].friends_ids = friends2;
}
testing.c
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include "testing.h"
#include "data.c"
int main() {
data();
for (int x=0; x<3; x++) {
printf("%d\n", userdata[0].friends_ids[x]);
}
printf("\n");
for (int x=0; x<3; x++) {
printf("%d\n", userdata[1].friends_ids[x]);
}
}
testing.h
struct user {
size_t* friends_ids;
};
struct user userdata[2];
Output:
1
3
4
-1942895168
1680886992
-320301600
It's evident these are garbage values for userdata[1] but I am confused why does userdata[0] print correctly but userdata[1] outputs garbage values?
What I've tried is to allocate memory for the structs but I don't know if it's possible because I keep getting errors saying "initializer element is not constant" despite trying.
struct user *userdata = (struct user *)malloc(2*sizeof(struct user));
As mentioned in the comments, there is the potential for undefined behavior in the posted code, but I did not get that far as the posted code resulted in a run-time error: defreferencing out of bounds pointer on the first call to printf in the main function. (possibly due to UB)
Problems (and suggested fixes) are listed below.
void data() {...
Is not a valid function prototype, and should have thrown a warning. And for your purposes, even:
void data(void) {...
although valid, is not sufficient. Change it to:
void data(struct user User[2]) {...
By the way also the minimum signature for the main function prototype is:
int main(void){...
Once you have made these changes, and given your definition of struct user ,consider the additional edits to data and main: (note, the following suggestions are limited only to illustrate one method of using function arguments to pass/receive data. Program architecture, or other ways to define a struct are left for other discussions.)
void data(struct user User[2]) // pass struct as argument
{
size_t i;
int a[] = {1,2,3};
int b[] = {4,5,6};
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
{
userdata[0].friends_ids[i] = a[i];
userdata[1].friends_ids[i] = b[i];
}
}
int main(void) {
userdata[0].friends_ids = calloc(3, sizeof(size_t)); // create memory
userdata[1].friends_ids = calloc(3, sizeof(size_t));
data(&userdata[2] ); //populate struct pointers (pass pointer to struct)
// values returned from call to data() are refreshed and ready to use.
for (int x=0; x<3; x++) { // use struct data
printf("%d\n", userdata[0].friends_ids[x]);
}
printf("\n");
for (int x=0; x<3; x++) {
printf("%d\n", userdata[1].friends_ids[x]);
}
free(userdata[0].friends_ids); // free memory
free(userdata[1].friends_ids);
return 0;
}

Adding pointers to an array of pointers

I'm trying to make a program that for a given int value keeps the amount of dividers:
int amount_of_dividers and a list of those dividers: int* dividers
This is the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int value;
int amount;
int* dividers;
} Divide;
int main(){
Divide ** tt;
read_dividers(tt,5);
}
/* the functions "amount_of_dividers(int g)" and "dividers_of(int g, int amount)"
used in void read_divider are working properly, they are not needed for this question */
void read_divider(Divide *g){
scanf("%d",&(g->value));
g->amount = amount_of_dividers(g->value);
g->dividers = dividers_of(g->value,g->amount);
}
/* assuming that read_divider works, what causes read_dividerS to crash? */
void read_dividers(Divide ** t, int amount){
int i = 0;
t = malloc(amount*sizeof(Divide*));
for(i = 0;i<amount;i++){
read_divider(t[i]);
}
}
Read_dividers uses an array of pointers **t where i'm trying to fill each element of this array with a pointer to a Divide g variable.
EDIT: input in this case in main() : "read_dividers(tt,5)" means the user gives 5 int's, which get converted to 5 Divide structs.
What happens instead is the program crashes after I give in the second int
If any more information is missing, don't hesitate to ask!
You are passing an uninitialized t[i] to read_divider. t is supposed to be pointer to pointer to Divide, not pointer to Divide, you may have just got lucky on your first pass, but I suspect it failed on the very first call.

FFTPACK in C examples

I'm trying to use FFTPACK converted from Fortran to C that I downloaded from Netlib (http://www.netlib.org/fftpack/). Unfortunately it seems to not really documented, and very cryptic (as I imagine most FFT codes are). Apparently it should follow a similar structure to the original Fortran code, so that's what I tried.
Here's what I have so far:
void main()
{
int n = 10;
float* wsave;
forward_transform(function1, wsave, n);
}
void forward_transform(float (*f)(float), float* wsave, int n)
{
int *ifac;
int i;
float r[n];
for (i = 0; i< n; i++)//set function values
{
r[i] = f((float)(-M_PI + i*2*M_PI/(n-1)));
}
__ogg_fdrffti(n, *wsave, *ifac);//initialize
__ogg_fdrfftf(n, *r, *wsave, *ifac);//forward transform
}
This code manages to compile, but gives a segfault when I call __ogg_fdrffti. I tried entering via gbd into fft.c to see exactly where the error is, but I can't seem to do that (the code still segfaults at the same line in my forward_transform function) leading me to believe that I'm somehow making an error in how I'm passing the various arrays.
Does anyone have any experience with or examples of the C version of FFTPACK?
The variables initialized in these functions have to exist somewhere in memory. You are passing pointers instead.
Try
void main()
{
int n = 10;
float wsave;
forward_transform(function1, wsave, n);
}
void forward_transform(float (*f)(float), float wsave, int n)
{
int ifac;
int i;
float r[n];
for (i = 0; i< n; i++)//set function values
{
r[i] = f((float)(-M_PI + i*2*M_PI/(n-1)));
}
__ogg_fdrffti(n, &wsave, &ifac);//initialize
__ogg_fdrfftf(n, r, &wsave, &ifac);//forward transform
}
Notice that the pointers are created using the address operator & on actual variables.

Threads and parallel programming

Say I want to compute the product of n complex numbers.
What I'm trying to do is that compute the product of the 2*i and 2*i+1 (i=0;i<n/2) complex numbers in threads. ie, clump 2 numbers together and compute their product, therefore I shall get n/2 products. Then again perform the same action on these n/2 products. So on and so forth, and carry on till the value of n is 1.
Here's my code
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct complex{
int a;
int b;
};
struct complex arr[1000];
struct arg {
struct complex arr1;
struct complex arr2;
int i;
};
//struct arg *argv;
struct arg *argv=malloc(sizeof(struct arg));
void *multiplier(struct arg *argv)
{
int real,imaginary;
real=(argv->arr1.a)*(argv->arr2.a)-(argv->arr1.b)*(argv->arr2.b);
imaginary=(argv->arr1.a)*(argv->arr2.b)+(argv->arr1.b)*(argv->arr2.a);
arr[argv->i].a=real;
arr[argv->i].b=imaginary;
printf("real=%d imaginary=%d no=%d\n",real,imaginary,argv->i);
pthread_exit(0);
}
int main(void)
{
int n,i,j,flag=0,q;
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d + i%d",&arr[i].a,&arr[i].b);
for(i=0;i<n;i++)
printf("%d + i%d\n",arr[i].a,arr[i].b);
while(n!=0)
{
if(n%2==1)
flag=1;
else
flag=0;
for(i=0;i<n/2;i++)
{
argv->arr1.a=arr[2*i].a; /* SEG FAULT HERE */
argv->arr1.a=arr[2*i].b;
argv->arr2.a=arr[2*i+1].a;
argv->arr2.a=arr[2*i+1].b;
argv->i=i;
pthread_create(&tid,&attr,multiplier,(void *) argv);
}
pthread_join(tid,NULL);
if(flag==1)
{
arr[n/2].a=arr[n-1].a;
arr[n/2].b=arr[n-1].b;
}
n=n/2;
}
return(0);
}
However my code gives me seg fault at line 45. I've been trying to figure out what's wrong with it but to no avail. I probably might be making a fundamentally horrendous error, but do help me out.
EDIT 1:
Probably the most stupid error ever.
I can't allocate memory globally like the way I just did.
I just inserted the Malloc into the main function and the program works.
Each thread needs it's own memory passed in via argv to not overwrite the other thread data.
So you might liek to move this line
struct arg * argv = malloc(sizeof(struct arg));
to here:
for(i = 0; i < n/2; ++i)
{
struct arg * argv = malloc(sizeof(*argv));
argv->arr1.a = arr[2*i].a;
Also checking the result of the calls malloc() might not be a bad idea.
Then let the thread function free() its memory when its done with it:
void * multiplier(struct arg * argv)
{
...
free(argv);
pthread_exit(0);
}
Also the thread function to be passed to pthread_create()is defined as:
void *(*)(void *)
So you shall declare yours this way:
void * multiplier(void * pvargv)
{
struct arg * argv = pvargv;
...
It's pretty hard to figure out which of your lines is line 45.
Also, this looks very wrong:
struct arg *argv=malloc(5*sizeof(struct complex));
It's very rarely correct to mis-match types like that, and struct complex looks nothing like struct arg, so this really seems strange. Also, you shouldn't have a global named argv while u
First, I'm not sure if the memory size you allocate for argv is sane enough. Second, you modify this argv thing, create a thread and immediately overwrite it, probably, before the thread even gets its hands on it.

Resources