How to optimize my c code? - c

I tried to implement C code for Wavelet transform in FPGA (Zynq ZC 702) but the code get stuck and this is because of memory problem so I should optimize my code but I don't know how.
Can anyone please give me some ideas how to do that ?
This is the main of the code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "wavemin.h"
#include "waveaux.h"
#include "waveaux.c"
#include "wavemin.c"
int main() {
printf("Hello World1 \n\r");
wave_object obj;
wt_object wt;
float *inp, *out;
int N, i, J,k;
float temp[1280] = {};
char *name = "db4";
obj = wave_init(name);
printf("Hello World2 \n\r");
N = 1280;
inp = (float*)malloc(sizeof(float) * N);
out = (float*)malloc(sizeof(float) * N);
//wmean = mean(temp, N);
for (i = 0; i < N; ++i) {
inp[i] = temp[i];
printf("Hello World3 \n\r");
//printf("%g \n", inp[i]);
}
J = 4; //Decomposition Levels
wt = wt_init(obj, "dwt", N, J); // Initialize the wavelet transform object
printf("Hello World4 \n\r");
setDWTExtension(wt, "sym"); // Options are "per" and "sym". Symmetric is the default option
printf("Hello World5 \n\r");
setWTConv(wt, "direct");
printf("Hello World6 \n\r");
dwt(wt, inp); // Perform DWT
printf("Hello World7 \n\r");
//getDWTAppx(wt, out, wt->length[0]);
// printf("Approximation Coefficients Level 1 \n");
// for (i = 0; i < wt->length[0]; ++i) {
// printf("%g ", out[i]);
// }
// printf("\n\n");
for (k = 1; k <= J; ++k) {
getDWTDetail(wt, out, wt->length[k], k);
printf("Detail Coefficients Level %d Length %d \n",
k, wt - length[k]);
for (i = 0; i < wt->length[k]; ++i) {
printf("%g ", out[i]);
}
printf("\n\n");
}
wt_summary(wt);// Prints the full summary.
printf("Hello World8 \n\r");
wave_free(obj);
wt_free(wt);
free(inp);
free(out);
return 0;
}
The other part of the code where there is the function used in the main function:
#include "wavemin.h"
wave_object wave_init(char *wname) {
wave_object obj = NULL;
int retval;
retval = 0;
if (wname != NULL) {
retval = filtlength(wname);
}
obj = (wave_object)malloc(sizeof(struct wave_set) + sizeof(float) * 4 *
retval);
obj->filtlength = retval;
obj->lpd_len = obj->hpd_len = obj->lpr_len = obj->hpr_len = obj->filtlength;
strcpy(obj->wname, wname);
if (wname != NULL) {
filtcoef(wname, obj->params, obj->params + retval, obj->params + 2 *
retval, obj->params + 3 * retval);
}
obj->lpd = &obj->params[0];
obj->hpd = &obj->params[retval];
obj->lpr = &obj->params[2 * retval];
obj->hpr = &obj->params[3 * retval];
return obj;
}
wt_object wt_init(wave_object wave, char *method, int siglength, int J) {
int size, i, MaxIter;
wt_object obj = NULL;
size = wave->filtlength;
MaxIter = wmaxiter(siglength, size);
if (!strcmp(method, "dwt") || !strcmp(method, "DWT")) {
obj = (wt_object)malloc(sizeof(struct wt_set) + sizeof(float) *
(siglength + 2 * J * (size + 1)));
obj->outlength = siglength + 2 * J * (size + 1); // Default
strcpy(obj->ext, "sym"); // Default
}
obj->wave = wave;
obj->siglength = siglength;
obj->J = J;
obj->MaxIter = MaxIter;
strcpy(obj->method, method);
if (siglength % 2 == 0) {
obj->even = 1;
}
else {
obj->even = 0;
}
strcpy(obj->cmethod, "direct"); // Default
obj->cfftset = 0;
obj->lenlength = J + 2;
obj->output = &obj->params[0];
if (!strcmp(method, "dwt") || !strcmp(method, "DWT")) {
for (i = 0; i < siglength + 2 * J * (size + 1); ++i) {
obj->params[i] = 0.0;
}
}
//wave_summary(obj->wave);
return obj;
}
static void dwt_sym(wt_object wt, float *inp, int N, float *cA, int len_cA,
float *cD, int len_cD) {
int i, l, t, len_avg;
len_avg = wt->wave->lpd_len;
for (i = 0; i < len_cA; ++i) {
t = 2 * i + 1;
cA[i] = 0.0;
cD[i] = 0.0;
for (l = 0; l < len_avg; ++l) {
if ((t - l) >= 0 && (t - l) < N) {
cA[i] += wt->wave->lpd[l] * inp[t - l];
cD[i] += wt->wave->hpd[l] * inp[t - l];
printf("world1 \n\r");
}
else if ((t - l) < 0) {
cA[i] += wt->wave->lpd[l] * inp[-t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[-t + l - 1];
printf("world2 \n\r");
}
else if ((t - l) >= N) {
cA[i] += wt->wave->lpd[l] * inp[2 * N - t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[2 * N - t + l - 1];
printf("world3 \n\r");
}
}
}
}
void dwt(wt_object wt, float *inp) {
int i, J, temp_len, iter, N, lp;
int len_cA;
float *orig, *orig2;
temp_len = wt->siglength;
J = wt->J;
wt->length[J + 1] = temp_len;
wt->outlength = 0;
wt->zpad = 0;
orig = (float*)malloc(sizeof(float) * temp_len);
orig2 = (float*)malloc(sizeof(float) * temp_len);
for (i = 0; i < wt->siglength; ++i) {
orig[i] = inp[i];
printf("Hello1 \n\r");
}
if (wt->zpad == 1) {
orig[temp_len - 1] = orig[temp_len - 2];
printf("Hello2 \n\r");
}
N = temp_len;
lp = wt->wave->lpd_len;
if (!strcmp(wt->ext, "sym")) {
//printf("\n YES %s \n", wt->ext);
i = J;
while (i > 0) {
N = N + lp - 2;
N = (int)ceil((float)N / 2.0);
wt->length[i] = N;
wt->outlength += wt->length[i];
i--;
}
wt->length[0] = wt->length[1];
wt->outlength += wt->length[0];
N = wt->outlength;
printf("Hello3 \n\r");
for (iter = 0; iter < J; ++iter) {
len_cA = wt->length[J - iter];
N -= len_cA;
dwt_sym(wt, orig, temp_len, orig2, len_cA, wt->params + N, len_cA);
temp_len = wt->length[J - iter];
printf("Hello4 \n\r");
if (iter == J - 1) {
for (i = 0; i < len_cA; ++i) {
wt->params[i] = orig2[i];
printf("Hello5 \n\r");
}
} else {
for (i = 0; i < len_cA; ++i) {
orig[i] = orig2[i];
printf("Hello6 \n\r");
}
}
}
} else {
printf("Signal extension can be either per or sym");
exit(-1);
}
free(orig);
free(orig2);
}
void setDWTExtension(wt_object wt, char *extension) {
if (!strcmp(extension, "sym")) {
strcpy(wt->ext, "sym");
} else {
printf("Signal extension can be either per or sym");
exit(-1);
}
}
void setWTConv(wt_object wt, char *cmethod) {
if (!strcmp(cmethod, "direct")) {
strcpy(wt->cmethod, "direct");
}
}
void getDWTDetail(wt_object wt, float *detail, int N, int level) {
/*
returns Detail coefficents at the jth level where j = 1,2,.., J
and Wavelet decomposition is stored as
[A(J) D(J) D(J-1) ..... D(1)] in wt->output vector
Use getDWTAppx() to get A(J)
Level 1 : Length of D(J), ie N, is stored in wt->length[1]
Level 2 :Length of D(J-1), ie N, is stored in wt->length[2]
....
Level J : Length of D(1), ie N, is stored in wt->length[J]
*/
int i, iter, J;
J = wt->J;
if (level > J) {
printf("The decomposition only has %d levels", J);
}
iter = wt->length[0];
for (i = 1; i < level; ++i) {
iter += wt->length[i];
}
for (i = 0; i < N; ++i) {
detail[i] = wt->output[i + iter];
}
}
void getDWTAppx(wt_object wt, float *appx, int N) {
/*
Wavelet decomposition is stored as
[A(J) D(J) D(J-1) ..... D(1)] in wt->output vector
Length of A(J) , N = wt->length[0]
*/
int i;
for (i = 0; i < N; ++i) {
appx[i] = wt->output[i];
}
}
void wt_summary(wt_object wt) {
int i;
int J, t;
J = wt->J;
printf("Wavelet Coefficients are contained in vector : %s \n", "output");
printf("\n");
printf("Approximation Coefficients \n");
printf("Level %d Access : output[%d] Length : %d \n",
1, 0, wt->length[0]);
printf("\n");
printf("Detail Coefficients \n");
t = wt->length[0];
for (i = 0; i < J; ++i) {
printf("Level %d Access : output[%d] Length : %d \n",
i + 1, t, wt->length[i + 1]);
t += wt->length[i + 1];
}
printf("\n");
}
void wave_free(wave_object object) {
free(object);
}
void wt_free(wt_object object) {
free(object);
}
enter image description here

In your code
Always check if malloc has returned non NULL value
Check your stack and heap settings in the linker file as you declare massive local variables and do a lots of mallocs - I suspect the (nomen omen)stack overflow, or failed mallocs.
Is it a bare metal program or you run it under some kind of OS?

Just for a matter of style and concision, I would rewrite this:
if (siglength % 2 == 0) {
obj->even = 1;
}
else {
obj->even = 0;
}
Into the following code:
obj->even = !(siglength % 2);
Or, alternatively:
obj->even = (siglength % 2) ? 0 : 1;
Also, I think there is room for optimization in this function:
static void dwt_sym(wt_object wt, float *inp, int N, float *cA, int len_cA,
float *cD, int len_cD) {
int i, l, t, len_avg;
len_avg = wt->wave->lpd_len;
for (i = 0; i < len_cA; ++i) {
t = 2 * i + 1;
cA[i] = 0.0;
cD[i] = 0.0;
for (l = 0; l < len_avg; ++l) {
if ((t - l) >= 0 && (t - l) < N) {
cA[i] += wt->wave->lpd[l] * inp[t - l];
cD[i] += wt->wave->hpd[l] * inp[t - l];
printf("world1 \n\r");
}
else if ((t - l) < 0) {
cA[i] += wt->wave->lpd[l] * inp[-t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[-t + l - 1];
printf("world2 \n\r");
}
else if ((t - l) >= N) {
cA[i] += wt->wave->lpd[l] * inp[2 * N - t + l - 1];
cD[i] += wt->wave->hpd[l] * inp[2 * N - t + l - 1];
printf("world3 \n\r");
}
}
}
}
First, you are always referring to t - 1 and never t itself, so why not have:
t = 2 * i;
And, I can guess that a lot of computation can be placed outside of the inner loop... If you want to optimize, there are many good candidate here.
One last word about optimization!
You should first profile your software and see where you spend the most time before thinking about optimization. You cannot optimize "in the air" without knowing where your software does really struggle. Consider using gprof.
PS: You should never ever use the letter l (ell) as a variable... it is way to close from the number 1 (one). Consider changing this is also, it can improve the reading.

Related

How to get rid of segmentation fault?

#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
int getCharNum(int a) { return a / (8 * sizeof(char)); }
int getBitNum(int a) { return a % (8 * sizeof(char)); }
int fromCharNum(int a) { return a * 8 * sizeof(char); }
int get2DimI(int a) { return getCharNum(a) / 187500; }
int get2DimJ(int a) { return getCharNum(a) % 187500; }
void rle_compress(char *src, char *dst, int ls, int *ld) {
uint8_t t[129];
int i, j = 0, k = 0, keep;
char out[187500];
t[0] = src[j];
while (j++ < ls) {
t[1] = src[j];
if (t[0] != t[1]) {
i = 1;
if (j < ls)
do
t[++i] = src[++j];
while (j < ls && i < 128 && t[i] != t[i - 1]);
if ((keep = t[i] == t[i - 1]))
--i;
out[k++] = (char)i;
t[0] = t[i];
if (!keep)
continue;
}
i = 2;
do
t[1] = src[++j];
while (++i < 130 && t[0] == t[1]);
out[k++] = i + 125;
out[k++] = t[0];
t[0] = t[1];
}
ld = &k;
dst = out;
}
void rle_extract(char *src, char *dst, int ls) {
int i, j, l = 0, k = 0, max;
char out[187500];
j = 0;
while (k + 2 < ls) {
i = src[k++]; //segfault
j = src[k++];
max = i + (i < 128 ? 1 : -126);
while (max--)
out[l++] = j;
}
dst = out;
return 0;
}
int main(void) {
int32_t n = 0;
scanf("%d", &n);
int32_t a[n];
int32_t b[] = { -1, -1, -1 };
char **count;
count = (char**)malloc(1000 * sizeof(char*));
int count_l[] = { [999] = 0 };
for (int i = 0; i < 1000; ++i) {
count[i] = (char*)malloc(187500 * sizeof(char));
char *temp = NULL;
rle_compress(count[i], temp, 187500, &count_l[i]);
free(count[i]);
count[i] = temp;
}
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
for (int i = 0; i < n; i++) {
char *src = count[get2DimI(a[i]) / 187500];
char dst[187500];
rle_extract(src, dst, count_l[i / 187500]);
dst[get2DimJ(a[i])] ^= 1 << (getBitNum(a[i]));
rle_compress(dst, count[get2DimI(a[i]) / 187500], 187500, &count_l[i]);
}
int32_t mv = 187500000 / (8 * sizeof(char));
int j = 0;
for (int i = 0; i < mv; i++) {
char *src = count[i / 187500];
char dst[187500];
rle_extract(src, dst, count_l[i / 187500]);
int32_t x = dst[i % 187500];
if (x == 0)
continue;
for (int k = 0; k < 8 * sizeof(char); k++) {
if ((x >> (k)) & 1) {
b[j++] = fromCharNum(i) + k;
}
}
//free(dst);
}
int m1 = min(b[0], min(b[1], b[2])),
m3 = max(b[0], max(b[1], b[2])),
m2 = b[0] + b[1] + b[2] - m1 - m3;
printf("%d %d %d", m1, m2, m3);
for (int i = 0; i < 1000; ++i)
free(count[i]);
free(count);
return 0;
}
How to fix this code?
I'm trying to compress byte array (which should compress greatly as n should be <=1500000 and numbers are from 0 to 1.5*10^9), but code gives me segfault on all testing inputs which I've tried. Without compress everything worked like a charm, but needed a lot of memory (and limits are 64MiB).
The code is obscure but there are some major problems:
void rle_extract(char *src, char *dst, int ls) does not take the output buffer from its caller, nor does it return a pointer to it: dst = out; just updates the argument value, not the caller's variable passed as an argument. Furthermore return 0; from a void function is incorrect too.
in any case, rle_extract should not return its local out buffer because it is only defined during the execution of the function and is discarded as soon as the function returns.
You should either pass the buffer as an argument or allocate it locally and return the pointer to the caller.
There might be other problems, there is no explanation for what the code is supposed to do.

C Program runs in repl it compiler but not on gcc (seg fault) Cant find it

Apologies for the horrible indentation. For whatever reason it wont paste with it.
As in the title Im getting a segmentation error pointing to both main and ReadData funtion. However it doesnt say in which line. Ive tried multiple changes and it end sup in the same.
edit: gdb gives me:at vfscanf.c:1898 1898 vfscanf.c: No such file or directory.
As input Im using in.txt with:
-1 1 5 14
3 1
-6 -2
-4 2
4 -4
2 4
-1 3
2 2
0 -2
-4 -2
-6 6
4 4
-2 4
2 -2
-4 6
C CODE:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
/* point structure to store x & y co-ordinates */
typedef struct {
int x, y;
}
point;
/* Prototype declarations*/
point * ReadData(point * center, int * radius, int * nPoints);
point * FilterData(point * data, point center, int radius, int * nPoints);
void Merge(point * data, int p, int q, int r);
void MergeSort(point * data, int p, int r);
void BinarySearch(point * data, int nPoints, point p);
void SearchPhase(point * data, int nPoints);
int main() {
point * data, * filter;
point center;
FILE * fp = fopen("out.txt", "w"); // output file out.txt
int radius, nPoints, i;
data = ReadData( & center, & radius, & nPoints); //call of ReadData()
filter = FilterData(data, center, radius, & nPoints); // call of FilterData()
MergeSort(filter, 0, nPoints - 1); // call of MersgeSort()
for (i = 0; i < nPoints; i++)
fprintf(fp, "%d\t%d\n", filter[i].x, filter[i].y); // writing to output file
fclose(fp);
printf("Filtered and sorted data written to out.txt");
SearchPhase(filter, nPoints); // call of SearchPhase()
return 0;
}
point * ReadData(point * center, int * radius, int * nPoints) {
FILE * fp = fopen("in.txt", "r"); // input file in.txt
point * ptr;
int i, n;
/* reading of center radius and no. of poins from file*/
fscanf(fp, "%d%d%d%d", & center - > x, & center - > y, radius, nPoints);
n = * nPoints;
ptr = (point * ) malloc(sizeof(point) * n); // dynamic memory allocation
for (i = 0; i < n; i++)
fscanf(fp, "%d%d", & ptr[i].x, & ptr[i].y); // reading of x and y from file
fclose(fp);
return ptr;
}
point * FilterData(point * data, point center, int radius, int * nPoints) {
point * filter;
int n = * nPoints, i, j, pos, x, y;
double dist;
int * a = (int * ) calloc(sizeof(int), n); // dynamic memory allocation
for (i = 0, j = 0; i < n; i++) {
x = data[i].x;
y = data[i].y;
dist = sqrt(pow(center.x - x, 2) + pow(center.y - y, 2)); // distance between center and point
if (dist <= (double) radius) // if distance <= radius then point is within circle
{
a[j] = i;
j++;
}
}
* nPoints = j;
filter = (point * ) malloc(sizeof(point) * j); // dynamic memory allocation
for (i = 0; i < j; i++) {
pos = a[i];
filter[i] = data[pos];
}
return filter;
}
/* Merge()*/
void Merge(point * data, int p, int q, int r) {
int n1 = q - p + 1;
int n2 = r - q;
point L[n1 + 1], R[n2 + 1];
int i, j, k;
for (i = 0; i < n1; i++)
L[i] = data[p + i];
for (j = 0; j < n2; j++)
R[j] = data[q + 1 + j];
point sentinel;
sentinel.x = 999;
sentinel.y = 999;
L[n1] = sentinel;
R[n2] = sentinel;
i = 0, j = 0;
for (k = p; k <= r; k++) {
if (L[i].x < R[j].x || (L[i].x == R[j].x && L[i].y < R[j].y)) {
data[k] = L[i];
i++;
} else {
data[k] = R[j];
j++;
}
}
}
/* MergeSort()*/
void MergeSort(point * data, int p, int r) {
int q, i;
if (p < r) {
q = (p + r) / 2;
MergeSort(data, p, q);
MergeSort(data, q + 1, r);
Merge(data, p, q, r);
}
}
/* BinarySearch()*/
void BinarySearch(point * data, int nPoints, point p) {
int l = 0, u = nPoints - 1, m, flag = 0;
while (l <= u) {
m = (l + u) / 2;
if (data[m].x == p.x && data[m].y == p.y) {
flag = 1;
break;
} else if (p.x < data[m].x || (p.x == data[m].x && p.y < data[m].y))
u = m - 1;
else
l = m + 1;
}
if (flag)
printf("\nOutput: Found at record %d", m + 1);
else
printf("\nOutput: Not Found");
}
/*SearchPhase()*/
void SearchPhase(point * data, int nPoints) {
point p;
while (1) {
printf("\nSearch input ( x y): ");
scanf("%d%d", & p.x, & p.y);
if (p.x == -999 || p.y == -999) {
printf("\nOutput: Exit\n");
break;
}
BinarySearch(data, nPoints, p);
}
}

Am I getting a segmentation fault due to an incorrect realloc?

struct model
{
char *cam;
int *to_location, *go_location;
int to_count, go_count;
int length, size;
};
struct model *
initialize(int l)
{
struct model *c;
c = (struct model *)malloc(sizeof(struct model));
assert(c != NULL);
c->length = l;
c->size = 2 * l;
c->cam = (char *)malloc(2 * l * sizeof(char));
assert(c->cam != NULL);
c->to_location = (int *)malloc(l * sizeof(int));
assert(c->to_location != NULL);
c->go_location = (int *)malloc(l * sizeof(int));
assert(c->go_location != NULL);
return c;
}
void
shuffle(struct model *current, struct model *future, int to, int g)
{
int i1, k, d1;
char init[100000];
current->to_count = 0;
current->go_count = 0;
for (i1 = 0; i1 < g; i1++)
{
init[i1] = 'G';
}
for (i1 = g; i1 < g + to; i1++)
{
init[i1] = 'T';
}
for (i1 = g + to; i1 < current->length; i1++)
{
init[i1] = '.';
}
for(i1 = 0; i1 < future->length; i1++)
{
d1 = rand() % current->length;
current->cam[i1] = init[d1];
if (current->cam[i1] == 'T')
{
current->to_location[current->to_count] = i1;
current->to_count = current->to_count + 1;
}
if (current->cam[i1] == 'G')
{
current->go_location[current->go_count] = i1;
current->go_count = current->go_count + 1;
}
for (k = d1; k < current->length; k++)
{
init[k] = init[k + 1];
}
current->length = current->length - 1;
}
current->length = future->length;
}
void
display(struct model *current)
{
int i;
printf("\n<");
current->to_count = 0;
current->go_count = 0;
for(i = 0; i < current->length; i++)
{
if (current->cam[i] == 'T')
{
current->to_location[current->to_count] = i;
current->to_count = current->to_count + 1;
}
else if (current->cam[i] == 'G')
{
current->go_location[current->go_count] = i;
current->go_count = current->go_count + 1;
}
printf("%c", current->cam[i]);
}
printf(">\n");
printf("\nThe total number of to's are %d, and the total number of gos are %d. The length is %d\n", current->to_count, current->go_count, current->length);
}
void
insert(struct model *current, struct model *future)
{
int j, k;
k = rand() % (current->length + 1);
current->length = current->length + 1;
for (j = current->length; j > k; j--)
{
future->cam[j] = future->cam[j - 1];
}
future->cam[k] = 'T';
future->size = 2 * current->length;
future->cam = (char *)realloc(future->cam, future->size * sizeof(char));
assert(future->cam != NULL);
current->size = 2 * current->length;
current->cam = (char *)realloc(current->cam, current->size * sizeof(char));
assert(current->cam != NULL);
}
int
main()
{
int l, to, go, i, k1, k2, j;
l = 100; //l,go,to are positive
go = 20;
to = 20; //go+to cannot be greater than l
struct model *current = initialize(l), *future = initialize(l);
shuffle(current, future, to, go);
display(current);
for (i = 0; i < 500; i++)
{
for (j = 0; j < current->length; j++)
{
future->cam[j] = current->cam[j];
}
insert(current, future);
for (j = 0; j < current->length; j++)
{
current->cam[j] = future->cam[j];
}
display(current);
}
return 0;
}
I am not able to find out the reason for a segmentation fault. I checked to see if I had implemented realloc correctly but from what I can tell there might not be a mistake there. the segmentation fault occurs after current->length reaches 281, so reallocation may be occurring uptill there as the initial size is 200 but why does it stop after that?
In initialize() you:
c->cam = (char *)malloc(2 * l * sizeof(char));
assert(c->cam != NULL);
c->to_location = (int *)malloc(l * sizeof(int));
assert(c->to_location != NULL);
c->go_location = (int *)malloc(l * sizeof(int));
assert(c->go_location != NULL);
And then in insert() you:
current->length = current->length + 1;
....
future->size = 2 * current->length;
future->cam = (char *)realloc(future->cam, future->size * sizeof(char));
assert(future->cam != NULL);
current->size = 2 * current->length;
current->cam = (char *)realloc(current->cam, current->size * sizeof(char));
And then in display() you:
current->to_count = 0;
current->go_count = 0;
for(i = 0; i < current->length; i++)
...
current->to_location[current->to_count] = i;
current->to_count = current->to_count + 1;
...
current->go_location[current->go_count] = i;
current->go_count = current->go_count + 1;
A similar thing also happens in shuffle()
So you write to to to_location from 0 up to current->length and current->length continues getting bigger because of insert() and yet to_location does NOT get bigger so as soon as current->length is increased you write past the end of the to_location array and clobber something important - eventually killing the program.

Undefined reference to 'function' error in C

I created a header file called ofdm.h which includes all the function prototypes. Then I created a source file called ofdm.c, which includes the source code of all the functions declared in ofdm.h . After that I started coding in main.c, but when I run it I get the error: undefined reference to '(function name)'. I get this error for all my functions.
Below you can find the source code of all my three files.
ofdm.h
#ifndef OFDM_H_INCLUDED
#define OFDM_H_INCLUDED
typedef struct {
double real, img;
} Complex;
char** split(char *s, const char *delim);
void parseComplex(Complex *c, char *line);
void rbits(short* buf, int nbits);
void printbinary(short* buf, int len);
void printcomplex(Complex* buf, int len);
long bin2dec(short *bin, int len);
void dec2bin(long dec, short *bin, int len);
void binaryadd(short *bin1, short *bin2, short *erg, int len);
void leftshift(short *bin,short *erg,int shifts, int len);
void binarymult(short *bin1, short *bin2, short *erg, int len);
void binarypower(short *bin,short *erg,int power, int len);
void scrambler(short *seed, short *input, short *output, int len, int seedlen);
void encoder(short *input, short *output, int inputlen);
void interleaver(short *input, short *output, int N_CBPS,int N_BPSC);
void deinterleaver(short *input, short *output, int N_CBPS,int N_BPSC);
void fixed_point(short* input, int nbits);
void fixed_point_complex(Complex* input, int nbits);
void defixed_point(short* input, int nbits);
void BPSKmapping(short* input, short* output, int nbits);
void BPSKdemapping(short* input, short* output, int nbits);
void QPSKmapping(short* input, Complex* output, int nbits);
void QPSKdemapping(Complex* input, short* output, int nbits);
void IFFT_BPSK(short* input, Complex* output, Complex* twidder);
void IFFT_QPSK(Complex* input, Complex* output, Complex* twidder);
double uniform(double a, double b);
double gauss(double mean, int SNRdb);
void ChannelModel(Complex R[], Complex S[], int SNRdb);
#endif
ofdm.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "ofdm.h"
char** split(char* string, const char* delim)
{
char* p;
int i = 0;
char** array = malloc(strlen(string) * sizeof(char*));
p = strtok(string, delim);
while(p != NULL)
{
array[i] = malloc(sizeof(char));
array[i++] = p;
p = strtok(NULL, delim);
}
return array;
}
void parseComplex(Complex *cmplx, char *number)
{
char *copy = number;
if(strchr(copy, ' ') != NULL)
{
char **result = split(copy, " ");
cmplx->real = atof(*result++);
char *sign = *result++;
cmplx->img = atof(*result++);
if(sign[0] == '-')
cmplx->img = -(cmplx->img);
}
else if(strchr(copy, 'j') != NULL)
{
cmplx->real = 0;
cmplx->img = atof(copy);
}
else
{
cmplx->real = atof(copy);
cmplx->img = 0;
}
}
void rbits(short* buf, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
buf[i] = (rand() % 2);
}
void printbinary(short* buf, int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("%d\t", buf[i]);
}
printf("\n\n\n");
}
void printcomplex(Complex* buf, int len)
{
int i;
for(i = 0; i < len; i++)
{
printf("%.0lf %.0lf\t", buf[i].real, buf[i].img);
}
printf("\n\n");
}
long bin2dec(short *bin, int len)
{
long dec = 0;
int i;
for(i = 0;i < len;i++)
{
dec += bin[i]*pow(2.0,(double) (len - i -1));
}
return dec;
}
void dec2bin(long dec, short *bin, int len)
{
long temp = dec;
int i;
for(i = 0;i<len;i++)
{
bin[len - 1 - i] = temp % 2;
temp = temp/2;
}
}
void binaryadd(short *bin1, short *bin2, short *erg, int len)
{
int i;
short carry = 0;
short oldcarry = 0;
for(i = len - 1; i >= 0; i--)
{
if((bin1[i] + bin2[i] + oldcarry) > 1)
{
carry = 1;
}
else
{
carry = 0;
}
erg[i] = (bin1[i] + bin2[i] + oldcarry) % 2;
oldcarry = carry;
}
}
void leftshift(short *bin,short *erg,int shifts, int len)
{
int i;
for(i = 0;i < len - shifts;i++)
{
erg[i] = bin[i + shifts];
}
for(i = len - shifts;i < len;i++)
{
erg[i] = 0;
}
}
void binarymult(short *bin1, short *bin2, short *erg, int len)
{
int i;
short temp[len - 1];
for(i = 0;i < len;i++)
{
erg[i] = 0;
}
for(i = 0;i < len;i++)
{
if(bin2[i] == 1)
{
leftshift(bin1,temp,len - 1 - i,len);
binaryadd(temp,erg,erg,len);
}
}
}
void binarypower(short *bin,short *erg,int power, int len)
{
int i;
short temp[len - 1];
for(i = 0;i < len;i++)
{
temp[i] = 0;
}
temp[len - 1] = 1;
if(power > 1)
binarypower(bin,temp,power - 1,len);
binarymult(temp,bin,erg,len);
}
void scrambler(short *seed, short *input, short *output, int len, int seedlen)
{
int i;
short carry;
short sequence[len - 1];
for(i = 0; i < len; i++)
{
sequence[i] = (seed[0] + seed[3]) % 2;
carry = (seed[0] + seed[3]) % 2;
leftshift(seed,seed,1,seedlen);
seed[seedlen - 1] = carry;
output[i] = (sequence[i] + input[i]) % 2;
}
}
void encoder(short *input, short *output, int inputlen)
{
int i;
short SR[7] = {0,0,0,0,0,0,0};
short A;
short B;
for(i = 0; i < inputlen;i++)
{
leftshift(SR,SR,1,7);
SR[6] = input[i];
A = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) % 2;
B = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) % 2;
output[2*i] = A;
output[2*i + 1] = B;
}
}
/*
void decoder(short *input, short *output, int inputlen)
{
int i;
short SR[7] = {0}
short A;
short B;
short C1;
short C2;
for(i = 0; i < intputlen; i++)
{
leftshift(SR, SR, 1, 7)
SR[6] = input[i];
C1 = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) / 2;
C2 = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) / 2;
A = (SR[6] + SR[4] + SR[3] + SR[1] + SR[0]) - (2 * C1);
B = (SR[6] + SR[5] + SR[4] + SR[3] + SR[0]) - (2 * C2);
output[2*i] = A; // output[i/2] = A;
output[2*i + 1] = B; // output[i/2 + 1] = B;
}
}
*/
void interleaver(short *input, short *output, int N_CBPS,int N_BPSC)
{
int i;
int t;
int k;
int s;
short first_permutuation[N_CBPS - 1];
for (k = 0; k < N_CBPS; k++)
{
i = (N_CBPS/16)*(k % 16) + (k/16);
first_permutuation[i] = input[k];
}
s = fmax(N_BPSC/2,1);
for(i = 0; i < N_CBPS;i++)
{
t = s*(i/s) + (i + N_CBPS - ((16*i)/N_CBPS)) % s;
output[t] = first_permutuation[i];
}
}
void fixed_point(short* input, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] < 0)
input[i] *= 32768;
else input[i] *= 32767;
}
}
void fixed_point_complex(Complex* input, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i].real == -1 || input[i].img == -1)
input[i] *= 32768;
else input[i] *= 32767;
}
}
void defixed_point(short* input, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] < 0)
input[i] /= 32768;
else input[i] /= 32767;
}
}
void IFFT_BPSK(short* input, Complex* output, Complex* twidder)
{
int i, k;
for(i = 0; i < 64; i++)
{
for(k = 0; k < 64; k++)
{
output[i].real += (twidder[i][k].real * input[i]) / 64;
output[i].img += (twidder[i][k].img * input[i]) / 64;
}
}
}
void IFFT_QPSK(Complex* input, Complex* output, Complex* twidder)
{
int i, k;
for(i = 0; i < 64; i++)
{
for(k = 0; k < 64; k++)
{
output[i].real += (twidder[i][k].real * input[i].real) / 64;
output[i].img += (twidder[i][k].img * input[i].img) / 64;
}
}
}
void IFFT_QPSK2(Complex* input, Complex* output, Complex* twidder, int nbits)
{
int a, b, c, d, e, f, g, h, blocks;
int count1 = 7, count2 = 20, count3 = 28, count4 = 41;
int next = 0;
Complex ifft_qpsk_output[64];
blocks = nbits / 48;
for(a = 1; a <= blocks; a++)
{
// pilots
output[7].real = 32767;
output[21].real = 32767;
output[42].real = 32767;
output[56].real = -32768;
// some data
output[40].real = input[26 + (next * 48)].real;
output[40].img = input[26 + (next * 48)].img;
output[41].real = input[27 + (next * 48)].real;
output[41].img = input[27 + (next * 48)].img;
// zeroes
for(b = 28; b <= 39; b++)
output[b].real = 0;
// other data
for(c = 0; c <= 6; c++)
{
output[c].real = input[c + (next * 48)].real;
output[c].img = input[c + (next * 48)].img;
}
for(d = 8; d <= 20; d++)
{
output[d].real = input[count1++ + (next * 48)].real;
output[d].img = input[count1++ + (next * 48)].img;
}
for(e = 22; e <= 27; e++)
{
output[e].real = input[count2++ + (next * 48)].real;
output[e].img = input[count2++ + (next * 48)].img;
}
for(f = 43; f <= 55; f++)
{
output[f].real = input[count3++ + (next * 48)].real;
output[f].img = input[count3++ + (next * 48)].img;
}
for(h = 57; h <= 63; h++)
{
output[h].real = input[count4++ + (next * 48)].real;
output[h].img = input[count4++ + (next * 48)].img;
}
// IFFT function goes here
IFFT_QPSK(output, ifft_qpsk_output, twidder);
printcomplex(ifft_qpsk_output, 64);
next++;
}
}
void IFFT_BPSK2(short* input, short* output, Complex* twidder, int nbits)
{
int a, b, c, d, e, f, g, h, blocks;
int count1 = 7, count2 = 20, count3 = 28, count4 = 41;
int next = 0;
Complex ifft_bpsk_output[64];
blocks = nbits / 48;
for(a = 1; a <= blocks; a++)
{
// pilots
output[7] = 32767;
output[21] = 32767;
output[42] = 32767;
output[56] = -32768;
// some data
output[40] = input[26 + (next * 48)];
output[41] = input[27 + (next * 48)];
// zeroes
for(b = 28; b <= 39; b++)
output[b] = 0;
// other data
for(c = 0; c <= 6; c++)
output[c] = input[c + (next * 48)];
for(d = 8; d <= 20; d++)
output[d] = input[count1++ + (next * 48)];
for(e = 22; e <= 27; e++)
output[e] = input[count2++ + (next * 48)];
for(f = 43; f <= 55; f++)
output[f] = input[count3++ + (next * 48)];
for(h = 57; h <= 63; h++)
output[h] = input[count4++ + (next * 48)];
// IFFT function goes here
IFFT_BPSK(output, ifft_bpsk_output, twidder);
printcomplex(ifft_bpsk_output, 64);
next++;
}
}
void BPSKmapping(short* input, short* output, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] == 0)
output[i] = -1;
else output[i] = 1;
}
}
void BPSKdemapping(short* input, short* output, int nbits)
{
int i;
for(i = 0; i < nbits; i++)
{
if(input[i] == -1)
output[i] == 0;
else output[i] == 1;
}
}
void QPSKmapping(short* input, Complex* output, int nbits)
{
int i;
for(i = 0; i < nbits; i += 2)
{
if(input[i] == 0 && input[i+1] == 0)
{
output[i].real = -1;
output[i+1].img = -1;
}
else if(input[i] == 0 && input[i+1] == 1)
{
output[i].real = -1;
output[i+1].img = 1;
}
else if(input[i] == 1 && input[i+1] == 0)
{
output[i].real = 1;
output[i+1].img = -1;
}
else
{
output[i].real = 1;
output[i+1].img = 1;
}
}
}
void QPSKdemapping(Complex* input, short* output, int nbits)
{
int i;
for(i = 0; i < nbits; i += 2)
{
if(input[i].real == -1 && input[i+1].img == -1)
{
output[i] = 0;
output[i+1] = 0;
}
else if(input[i].real == -1 && input[i+1].img == 1)
{
output[i] = 0;
output[i+1] = 1;
}
else if(input[i].real == 1 && input[i+1].img == -1)
{
output[i] = 1;
output[i+1] = 0;
}
else
{
output[i] = 1;
output[i+1] = 1;
}
}
}
//Channel Begin
double uniform(double a, double b)
{
double c;
double d;
static int firstcall = 1;
c = b - a;
if(firstcall == 1)
{
srand((unsigned int)time(NULL));
firstcall = 0;
}
d = a + (double)rand() / RAND_MAX * c;
return d;
}
double gauss(double mean, int SNRdb)
{
double dGaussNum;
double x = 0;
int i;
double sigma;
sigma = 1 / pow(10, (double)SNRdb / 10);
for(i = 0;i < 12; i ++)
{
x = x + uniform(0,1);
}
x = x - 6;
dGaussNum = mean + sqrt(sigma) * x;
return dGaussNum;
}
void ChannelModel(Complex R[], Complex S[], int SNRdb)
{
int i;
for (i=0;i<N+L;i++)
{
R[i].real = S[i].real + gauss(0, SNRdb);
R[i].img = S[i].img + gauss(0, SNRdb);
}
}
//Channel End
void deinterleaver(short *input, short *output, int N_CBPS,int N_BPSC)
{
int i;
int t;
int k;
int s;
short first_permutuation[N_CBPS - 1];
s = fmax(N_BPSC/2,1);
for (t = 0; t < N_CBPS; t++)
{
i = s*(t/s) + (t + ((16*t)/N_CBPS)) % s;
first_permutuation[i] = input[t];
}
for(i = 0; i < N_CBPS;i++)
{
k = 16*i - (N_CBPS - 1)*((16*i)/N_CBPS);
output[k] = first_permutuation[i];
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ofdm.h"
int main(int argc, char *argv[])
{
short seed[8];
int bits, i, j, k;
char mode[5], line[1024];
/* Complex twidder[64][64];
FILE *file = fopen("twidder_factor.txt", "r");
i = 0;
while(fgets(line, sizeof(line), file ) != NULL)
{
k = j = 0;
char **result = split(line, "\t");
while(result[k] != NULL)
{
parseComplex(&twidder[i][j], result[k++]);
j++;
}
i++;
}
*/
printf("How many bits do you want to transmit?: ");
scanf("%d", &bits);
short* start_input;
short* scrambler_output;
short* encoder_output;
short* interleaver_output;
short* bpsk_mapper_output;
short* ifft_bpsk_input[64];
Complex* qpsk_mapper_output;
Complex ifft_qpsk_input[64];
start_input = malloc(sizeof(short) * bits);
scrambler_output = malloc(sizeof(short) * bits);
encoder_output = malloc(sizeof(short) * (bits * 2));
interleaver_output = malloc(sizeof(short) * (bits * 2));
bpsk_mapper_output = malloc(sizeof(short) * (bits * 2));
qpsk_mapper_output = malloc(sizeof(Complex) * (bits * 2));
if(qpsk_mapper_output == NULL)
{
fprintf(stderr, "Couldn't allocate that much memory!\n");
return 1;
}
srand(time(NULL));
rbits(seed, 8);
rbits(start_input, bits);
printf("Which modulation type to you want to use? (type BPSK or QPSK): ");
scanf("%s", mode);
if((strcmp(mode, "BPSK") == 0) || (strcmp(mode, "bpsk") == 0))
{
printf("\nSelected modulation type: BPSK\n\n\n");
printf("SCRAMBLER OUTPUT:\n\n");
scrambler(seed, start_input, scrambler_output, bits, 8);
printbinary(scrambler_output, bits);
printf("ENCODER OUTPUT:\n\n");
encoder(scrambler_output, encoder_output, bits);
printbinary(encoder_output, bits*2);
printf("INTERLEAVER OUTPUT:\n\n");
interleaver(encoder_output, interleaver_output, bits, 1);
printbinary(interleaver_output, bits*2);
printf("MAPPER OUTPUT:\n\n");
BPSKmapping(interleaver_output, bpsk_mapper_output, bits*2);
printbinary(bpsk_mapper_output, bits*2);
printf("FIXED-POINT OUTPUT:\n\n");
fixed_point(bpsk_mapper_output, bits*2);
printbinary(bpsk_mapper_output, bits*2);
/*
printf("IFFT OUTPUT:\n\n");
IFFT_BPSK(bpsk_mapper_output, ifft_bpsk_input, twidder, bits*2)
defixed_point(bpsk_mapper_output, bits*2);
printbinary(bpsk_mapper_output, bits*2);
*/ }
else if((strcmp(mode, "QPSK") == 0) || (strcmp(mode, "qpsk") == 0))
{
printf("\nSelected modulation type: QPSK\n\n\n");
printf("SCRAMBLER OUTPUT:\n\n");
scrambler(seed, start_input, scrambler_output, bits, 8);
printbinary(scrambler_output, bits);
printf("ENCODER OUTPUT:\n\n");
encoder(scrambler_output, encoder_output, bits);
printbinary(encoder_output, bits*2);
printf("INTERLEAVER OUTPUT:\n\n");
interleaver(encoder_output, interleaver_output, bits, 2);
printbinary(interleaver_output, bits*2);
printf("MAPPER OUTPUT:\n\n");
QPSKmapping(interleaver_output, qpsk_mapper_output, bits*2);
printcomplex(qpsk_mapper_output, bits*2);
/*
printf("FIXED-POINT OUTPUT:\n\n");
fixed_point_complex(qpsk_mapper_output, bits*2);
printcomplex(qpsk_mapper_output, bits*2);
printf("IFFT OUTPUT:\n\n");
IFFT_QPSK(qpsk_mapper_output, ifft_qpsk_input, twidder, bits*2)
defixed_point(qpsk_mapper_output, bits*2);
printbinary(qpsk_mapper_output, bits*2);
*/ }
else
{
printf("That's an invalid modulation type!\n");
free(start_input);
free(scrambler_output);
free(encoder_output);
free(interleaver_output);
free(bpsk_mapper_output);
free(qpsk_mapper_output);
return 0;
}
free(start_input);
free(scrambler_output);
free(encoder_output);
free(interleaver_output);
free(bpsk_mapper_output);
free(qpsk_mapper_output);
system("PAUSE");
return 0;
}
If you could help me to solve this problem I would be glad. I think there is some kind of linking problem between my library and the main source file.
Thanks in advance.
I guess you are compiling only main.c. You should also include ofdm.c.
$ gcc -Wall main.c ofdm.c -o output
Since you get this error for all your functions, it can't be a typo. My best guess is that you are not linking the two files.
If using gcc, this is done in the following way:
gcc -o main.o -c main.c
gcc -o ofdm.o -c ofdm.c
gcc -o program main.o ofdm.o
Note that -c means it should compile, but not try to create an executable. This means that linking is not done.
Once both files are compiled, you would then link them together.
When you're learning new things, it helps to learn one new thing at a time. Put your source code into version control, then simplify it to get a clean compile.
main.c
#include "ofdm.h"
int main(int argc, char *argv[])
{
return 0;
}
ofdm.c
#include "ofdm.h"
void leftshift(short *bin,short *erg,int shifts, int len)
{
int i;
for(i = 0;i < len - shifts;i++)
{
erg[i] = bin[i + shifts];
}
for(i = len - shifts;i < len;i++)
{
erg[i] = 0;
}
}
ofdm.h
#ifndef OFDM_H_INCLUDED
#define OFDM_H_INCLUDED
void leftshift(short *bin,short *erg,int shifts, int len);
#endif
Then, to compile with gcc . . .
$ gcc -Wall -c ofdm.c
$ gcc -Wall -c main.c
$ gcc -Wall *.o
That should give you a program that does nothing, successfully. Now you can start to build it up again from your version-controlled source.
Add one function at a time.
Edit it to get a clean compile.
Edit it to pass sane tests.
I came here with the same issue while using ESP-IDF as a beginner. What solved this for me was that I just forgot to add all the necessary sources in the idf_component_register function call.

Triangulation algorithm

I've decided to create a simple demo, dividing a polygon into triangle set. Here what i've got so far:
A sequential vertex list is given (P1) forming polygon edges (polygon is not convex in most cases); a triangle set is needed
Loop through all the vertices within the polygon P1 and find the one (v), which will satisfy next clauses:
remove v from polygon and save the new one to P2 previous vertex to v
connected to its next one form a
line which do not cross any of P2
edges
v is not inside P2
If these are satisfied, we can replace P1 with (P2 + triangle( prev(v), v, next(v)) ) and repeat this action until P1 contains more than 3 vertices.
So, the questions are: is this algorithm correct and how it could be implemented using C / C++ using the most obvious and simple way?
I think you're describing the ear clipping method. There's code for that method at http://cs.smith.edu/~orourke/books/ftp.html ; it's the code described in the book Computational Geometry in C.
Seems that i'm done with this algorithm implementation. Please, verify it someone. Thanks!
typedef struct Point
{
float x, y;
};
class MooPolygon
{
private:
vector<Point> points;
int isVertexEar(int n, const vector<Point> &p)
{
return (isVertexInsideNewPoly(n, p) && !isEdgeIntersect(n, p));
}
int isEdgeIntersect(int n, const vector<Point> &p)
{
Point v = p[n];
vector<Point> a;
for (size_t i = 0; i < p.size(); i++)
if (i != n)
a.push_back(p[i]);
int c = 0, cnt = a.size(), prev = (cnt + (n - 1)) % cnt, next = n % cnt;
Point v1 = a[prev], v2 = a[next];
for (size_t i = 0, j = cnt - 1; i < cnt; j = i++)
{
if (prev == i || prev == j || next == i || next == j)
continue;
Point v4 = a[j], v3 = a[i];
float denominator = ((v4.y - v3.y) * (v2.x - v1.x)) - ((v4.x - v3.x) * (v2.y - v1.y));
if (!denominator)
continue;
float ua = (((v4.x - v3.x) * (v1.y - v3.y)) - ((v4.y - v3.y) * (v1.x - v3.x))) / denominator;
float ub = (((v2.x - v1.x) * (v1.y - v3.y)) - ((v2.y - v1.y) * (v1.x - v3.x))) / denominator;
//float x = v1.x + (ua * (v2.x - v1.x)), y = v1.y + (ua * (v2.y - v1.y));
if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1)
{
c = 1;
break;
}
}
return c;
}
int isVertexInsideNewPoly(int n, const vector<Point> &p)
{
Point v = p[n];
vector<Point> a;
for (size_t i = 0; i < p.size(); i++)
if (i != n)
a.push_back(p[i]);
int c = 1;
for (size_t i = 0, j = a.size() - 1; i < a.size(); j = i++)
{
if ((((a[i].y <= v.y) && (v.y < a[j].y)) || ((a[j].y <= v.y) && (v.y < a[i].y))) && (v.x > (a[j].x - a[i].x) * (v.y - a[i].y) / (a[j].y - a[i].y) + a[i].x))
c = !c;
}
return c;
}
float dist(Point a, Point b)
{
return sqrt( ((a.x - b.x) * (a.x - b.x)) + (((a.y - b.y) * (a.y - b.y))) );
}
public:
void push(const Point &p)
{
for (size_t i = 0; i < points.size(); i++)
{
if (dist(points[i], p) < 7.f)
{
points.push_back(points[i]);
return;
}
}
points.push_back(p);
}
void pop()
{
if (points.size() > 0)
points.pop_back();
}
void clear()
{
points.clear();
}
Point v(int index)
{
return points[index];
}
size_t size()
{
return points.size();
}
void triangulate()
{
vector<Point> a;
for (size_t i = 0; i < points.size(); i++)
{
a.push_back(points[i]);
}
points.clear();
for (size_t t = a.size() - 1, i = 0, j = 1; i < a.size(); t = i++, j = (i + 1) % a.size())
{
if (a.size() == 3)
{
points.push_back(a[0]);
points.push_back(a[1]);
points.push_back(a[2]);
break;
}
if (isVertexEar(i, a))
{
points.push_back(a[t]);
points.push_back(a[i]);
points.push_back(a[j]);
a.erase(a.begin() + i, a.begin() + i + 1);
t = a.size() - 1;
i = 0;
j = 1;
}
}
}
};
The code has an error on the line below. The line is in the for loop in the push() function of your class:
points.push_back(points[i]);
You are not passing the pushed Point, but an empty element of the vector itself. I changed the line to
points.push_back(p);
and it worked.

Resources