guys. I've got a project where I'm given a number of chairs, a number of parasols, and the locations of the chairs. I think have to find the optimal width of all parasols (all equal to each other) to cover each chair. I crafted this bit of code that works for the sample cases in the assignment file (it's messy, but it works):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void search();
int* constructParasols();
int check();
void draw();
int main(void)
{
int n, k, totalSize;
scanf("%d", &n);
printf("\n");
scanf("%d", &k);
printf("\n");
int* chairs = (int*)calloc(n + 1, sizeof(int));
for (int i = 0; i < n; i++)
{
scanf("%d", &chairs[i]);
}
printf("\n");
totalSize = chairs[n - 1];
search(n, k, chairs, totalSize, 0, totalSize/k);
free(chairs);
chairs = NULL;
system("pause");
}
void search(int n, int k, int* chairs, int totalSize, int low, int hi)
{
int mid = (low + hi)/2;
int tempPos = 0;
if (low >= hi - 1)
{
if (check(n, k, low, chairs, constructParasols(k,totalSize,low), k - 2, totalSize - (low * 2), totalSize) == 1)
{
printf("width %d is optimal\n", low);
}
else if (check(n, k, hi, chairs, constructParasols(k, totalSize, hi), k - 2, totalSize - (low * 2), totalSize) == 1)
{
printf("width%d is optimal\n", hi);
}
else
{
printf("no solution found\n");
}
}
else if (check(n, k, mid, chairs, constructParasols(k, totalSize, mid), k - 2, totalSize - (mid * 2), totalSize) == 1)
{
search(n, k, chairs, totalSize, low, mid-1);
}
else
{
search(n, k, chairs, totalSize, mid+1, hi);
}
}
int* constructParasols(int k, int totalSize, int width)
{
int* parasols = (int*)calloc(k + 1, sizeof(int));
int tempPos = 0;
for (int i = 0; i < k - 1; i++)
{
parasols[i] = tempPos;
tempPos += width;
}
parasols[k - 1] = totalSize - width;
return parasols;
}
int check(int n, int k, int width, int* chairs, int* parasols, int pNum, int maxPos, int totalSize)
{
int* cover = (int*)calloc(totalSize + 1, sizeof(int));
int failed = 0;
for (int i = 0; i < totalSize; i++)
{
cover[i] = 0;
}
if (k<=2)
{
draw(n, k, width, chairs, parasols, totalSize);
for (int i = 0; i < width; i++)
{
cover[i] = 1;
if(k==2) cover[parasols[1] + i] = 1;
}
for (int i = 0; i < n; i++)
{
if (cover[chairs[i] - 1] == 0)
{
failed = 1;
}
}
if (failed == 0)
{
free(cover);
cover = NULL;
free(parasols);
parasols = NULL;
return 1;
}
else
{
free(cover);
cover = NULL;
free(parasols);
parasols = NULL;
return 0;
}
}
draw(n, k, width, chairs, parasols, totalSize);
for (int i = 0; i < k; i++)
{
for (int j = 0; j < width; j++)
{
cover[parasols[i] + j] = 1;
}
}
for (int i = 0; i < n; i++)
{
if (cover[chairs[i]-1] == 0)
{
failed = 1;
}
}
if (failed == 0)
{
free(cover);
cover = NULL;
free(parasols);
parasols = NULL;
return 1;
}
if (pNum <= 1 && parasols[pNum] == maxPos)
{
free(cover);
cover = NULL;
free(parasols);
parasols = NULL;
return 0;
}
else if (parasols[pNum] == maxPos)
{
free(cover);
cover = NULL;
return check(n, k, width, chairs, parasols, pNum - 1, maxPos - width, totalSize);
}
else
{
free(cover);
cover = NULL;
parasols[pNum]++;
return check(n, k, width, chairs, parasols, pNum, maxPos, totalSize);
}
}
void draw(int n, int k, int width, int* chairs, int* parasols, int totalSize)
{
int* dCover = (int*)calloc(totalSize, sizeof(int));
int* chairPos = (int*)calloc(totalSize, sizeof(int));
for (int i = 0; i < totalSize; i++)
{
dCover[i] = 0;
chairPos[i] = 0;
}
for (int i = 0; i < k; i++)
{
for (int j = 0; j < width; j++)
{
if (dCover[parasols[i] + j] >= 1) dCover[parasols[i] + j] = 2;
else dCover[parasols[i] + j] = 1;
}
}
for (int i = 0; i < n; i++)
{
chairPos[chairs[i]-1] = 1;
}
for (int i = 0; i <= totalSize; i++)
{
if (dCover[i] == 2)
{
printf("=");
}
else if (dCover[i] == 1)
{
printf("-");
}
else
{
printf(" ");
}
}
printf("\n");
for (int i = 0; i <= totalSize; i++)
{
if (chairPos[i] == 1)
{
printf("|");
}
else
{
printf(" ");
}
}
printf("\n");
free(dCover);
dCover = NULL;
free(chairPos);
chairPos = NULL;
return;
}
(removed some comments and debug prints for clarity and reduced size)
However, these were only two samples shown out of the ten he will attempt. I want to get them all correct because I'm a perfectionist about programming, and I noticed a blind spot in the way I check if the cover works. Right now, it'll take the second parasol from the right and drag it space by space and check each time. Once it touches the parasol to the right of it, it'll start on the next parasol to the left, and do this until just the leftmost is remaining and conclude that this configuration won't succeed.
This means that if I give a sample input, such as 8 4 1 3 6 9 12 15 17 20,
it'll fail to check the situation in which the parasols are a width of 4 and evenly spaced out. I set out to rectify this, by changing this:
else
{
free(cover);
cover = NULL;
parasols[pNum]++;
return check(n, k, width, chairs, parasols, pNum, maxPos, totalSize);
}
(which is where it tries to push the parasol to the left and try again) to this:
else
{
printf("freeing cover\n");
free(cover);
cover = NULL;
printf("iteration failed\n");
//parasols[pNum]++;
//return check(n, k, width, chairs, parasols, pNum, maxPos, totalSize);
if (parasols[pNum] != parasols[pNum - 1] + width && check(n, k, width, chairs, parasols, pNum - 1, parasols[pNum]-width, totalSize) == 1)
{
return 1;
}
else
{
parasols[pNum]++;
return check(n, k, width, chairs, parasols, pNum, maxPos, totalSize);
}
}
Seemed to make sense. Only when I run it now, I get a read access violation. Right here:
else dCover[parasols[i] + j] = 1;
dCover. Under the draw command.
It'll grab the parasol and move it to the right, check it, then grab the parasol to the left of that and move it to the right. Just as I expected. It's only after
that in which it throws the exception.
If I revert the code, everything works perfectly. I have no idea how that relates to this - they're two different pointers entirely. I'm using Visual Studio 2017 to build this, if that makes a difference. Can someone help me out?
When you free already freed pointer you get this kind of crush.
You free parasols in check and continue to use it without reconstruct it.
in this part of your code:
if (parasols[pNum] != parasols[pNum - 1] + width && check(n, k, width, chairs, parasols, pNum - 1, parasols[pNum]-width, totalSize) == 1)
{
return 1;
}
else
{
parasols[pNum]++;
return check(n, k, width, chairs, parasols, pNum, maxPos, totalSize);
}
check was failed you free(parasols) and returned 0, so you get into the else and used it again in parasols[pNum]++ and also in the return check(... without reconstruct the parasols.
The program crash in the second free but may crush also when accesing the freed pointer.
Related
I'm currently working on an essay, in which I compare sorting times of certain algorithms. I've written an optimized version of bubble sort, which checks if there is a swap, if not, it stops.
void bubble_sort(int* tab, int n) {
int zamiana, x, i;
do {
zamiana = 0;
for (int counter = 0, i = 1; i < n; ++counter, ++i) {
if (tab[counter] > tab[i]) {
x = tab[counter];
tab[counter] = tab[i];
tab[i] = x;
zamiana = 1;
}
}
} while (zamiana != 0);
}
I have found that it takes almost 0s to sort array sorted in ascending order, now I'm testing it on an array sorted in descending order, and times are almost the same as for ascending order. Is it normal?
Code tested:
#include <time.h>
#include <stdio.h>
void quickSort(int* tab, int lewy, int prawy) {
int x, y = lewy - 1, z = prawy + 1, pivot = tab[(lewy + prawy) / 2];
while (1) {
while (pivot < tab[++y]);
while (pivot > tab[--z]);
if (y <= z) {
x = tab[y];
tab[y] = tab[z];
tab[z] = x;
}
else {
break;
}
}
if (z > lewy) {
quickSort(tab, lewy, z);
}
if (y < prawy) {
quickSort(tab, y, prawy);
}
}
void bubble_sort(int* tab, int n) {
int zamiana, x, i;
do {
zamiana = 0;
for (int counter = 0, i = 1; i < n; ++counter, ++i) {
if (tab[counter] > tab[i]) {
x = tab[counter];
tab[counter] = tab[i];
tab[i] = x;
zamiana = 1;
}
}
} while (zamiana != 0);
}
int main (){
int* tab;
int n;
srand(time(NULL));
scanf("%d", &n); //user input array size
tab = (int*)malloc(n * sizeof(int*));
for (int counter = 0; counter < n; ++counter) {
tab[counter] = (rand() % 200) - 100; //<-100;100>
}
quickSort(tab, 0, n); //sorting array to get descending order
clock_t start = clock();
bubble_sort(tab, n); //sorting array
clock_t end = clock();
float seconds = (float)(end - start) / CLOCKS_PER_SEC;
printf("Time elapsed: %f", seconds);
}
I implemented Parallel Merge sort in this code using the tree Structural scheme; but it doesn't sort the Array!
Could you take look at it and tell me what is wrong?
For communication among the processor I used the normal MPI_send() and MPI_recv().
However I used numbers 0 and 1 and 2 as tags for the fifth argument of MPI_recv().
For 8 processors the tree structural scheme gives the Array to the processor with rank 0 then it splits the array in half an gives the right half to processor 4 and keeps the left half.
Then the processor 4 splits its array in half an gives the right half to processor 6 and keeps the left half.
At the end with this scheme all the processors work an the program and none of them will idle.
Since at the leaves of the tree all the processors have a piece of Array to do sequential Merge_sort_inc on it.
text
#include<stdio.h>
#include<mpi.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
/* print_array() takes the elements of Array to the output */
void print_array(int arr[], int size)
{
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
/*copyarray() takes as first argument an Array a[] which its elements
between indexes start_a and end_a are to be copied to the dynamic Array *b with size of (size_b) */
void copyarray(int a[] ,int start_a , int end_a, int* b, int size_b)
{
int i = 0;
for (i = 0; i < size_b;i++)
{
b[i] = a[start_a];
start_a++;
if (start_a == end_a)
break;
}
}
/* merge () function is just the sequential implementation of merge Sort Algorithm */
void merge(int Arr[], int left, int mid, int right)
{
int n_l = (mid - left + 1);
int n_r = (right - mid);
int* Arr_l = (int*)calloc(n_l, sizeof(int));
int* Arr_r = (int*)calloc(n_r, sizeof(int));
if (Arr_l == NULL)
return;
if (Arr_r == NULL)
return;
for (int i = 0;i < n_l;i++)
Arr_l[i] = Arr[left + i];
for (int j = 0;j < n_r;j++)
Arr_r[j] = Arr[mid + 1 + j];
int i = 0, j = 0, k = left;
while (i < n_l && j < n_r)
{
if (Arr_l[i] <= Arr_r[j])
{
Arr[k] = Arr_l[i];
i++;
k++;
}
else
{
Arr[k] = Arr_r[j];
j++;
k++;
}
}
while (i < n_l)
{
Arr[k] = Arr_l[i];
i++;
k++;
}
while (j < n_r)
{
Arr[k] = Arr_r[j];
j++;
k++;
}
free(Arr_l);
free(Arr_r);
}
/*merge_sort_inc() is the sequential algorithm of sorting in increasing order*/
void merge_sort_inc(int Arr[], int left, int right)
{
int mid = (int)(left + (right - left) / 2);
if (left < right)
{
merge_sort_inc(Arr, left, mid);
merge_sort_inc(Arr, mid + 1, right - 1);
merge(Arr, left, mid, right);
}
}
/*parallelMerge() builds first the tree-structural communication between the processors. at the leafs of the tree,
where there is no more divide and concurrent progress the Function gives the the processor the sequential Merge sort algorithm*/
void parallelMerge(int* array, int size, int height)
{
int parent;
int rank;
int numberOfproc;
int next;
int rightChild;
//MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &numberOfproc);
parent = rank & ~(1 << height);
next = height - 1;
rightChild = rank | (1 << (height - 1));
if (height > 0)
if (rightChild >= numberOfproc)
parallelMerge(array, size, next);
else
{
int left_size = (int)(size / 2);
int right_size = size - left_size;
int* leftArray = (int*)calloc(left_size, sizeof(int));
int * rightArray = (int*)calloc(right_size,sizeof(int));
if (leftArray == NULL)
return;
if (rightArray == NULL)
return;
int massage[2];
int i, j , k;
MPI_Status status;
copyarray(array, 0, left_size, leftArray, left_size);
copyarray(array, size - left_size, size, rightArray,right_size);
massage[0] = next;
massage[1] = right_size;
MPI_Send(massage, 2, MPI_INT, rightChild,0, MPI_COMM_WORLD);
MPI_Send(rightArray, right_size, MPI_INT, rightChild, 1, MPI_COMM_WORLD);
parallelMerge(leftArray, left_size, next);
MPI_Recv(rightArray, right_size, MPI_INT, rightChild, 2, MPI_COMM_WORLD, &status);
i = j = k = 0;
while (i < left_size && j < right_size)
{
if (leftArray[i] < rightArray[j])
{
array[k] = leftArray[i]; i++, k++;
}
else
{
array[k] = rightArray[j]; j++, k++;
}
}
while (i<left_size)
{
array[k] = leftArray[i];
k++;
i++;
}
while (j<right_size)
{
array[k] = rightArray[j];
k++;
j++;
}
}
else
{
merge_sort_inc(array, 0 ,size);
if (parent != rank)
MPI_Send(array, size, MPI_INT, parent, 2, MPI_COMM_WORLD);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
/*building an array with the help of Random function*/
time_t t;
srand((unsigned)time(&t));
int Arr[100];
int arrSize = sizeof(Arr) / sizeof(int);
for (int i = 0; i < arrSize; i++)
Arr[i] = rand() / 100;
printf("the unsorted array is : \n ");
print_array(Arr, arrSize);
/*starting the parallel sorting*/
int rank;
int comm_size;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD , &rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
double start = MPI_Wtime();//capture time
if (rank == 0)
{
int roothight = 0;
int nodeCount = 1;
while (nodeCount < comm_size)
nodeCount++;
roothight = (int)log(nodeCount);
int* newarray = (int*)calloc(arrSize, sizeof(int));
if (newarray == NULL)
return 1;
copyarray(Arr, 0, arrSize - 1, newarray, arrSize );
parallelMerge(newarray, arrSize, roothight);
double midle = MPI_Wtime();
}
else
{
int massage[2];
int height;
int size_array;
MPI_Status status;
MPI_Recv(massage, 2, MPI_INT, MPI_ANY_SOURCE,0, MPI_COMM_WORLD, &status);
height = massage[0];
size_array = massage[1];
int* newarray = (int*)calloc(size_array, sizeof(int));
if (newarray == NULL)
return 1;
MPI_Recv(newarray, size_array, MPI_INT, MPI_ANY_SOURCE,1, MPI_COMM_WORLD, &status);
parallelMerge(newarray, size_array, height);
}
double end = MPI_Wtime();
MPI_Finalize();
printf("\n the sorted array is : \n");
print_array(Arr, arrSize);
printf("\n the sorting takes %lf time ", (end - start));
return 0;
}
The task is to find the longest contiguous sub-array with all elements distinct.
Example Input {4, 3, 1, 3, 2, 1, 0} Output {3, 2, 1, 0}
Algorithm
Extract first sub Array (here 431)
Extract second sub Array (here 31)
Compare number of elements and keep the array with the biggest number (keep 431)
Return to 2
Problem The output is incorrect
/* Free old array and replace it by the new array
* If we only want to free old array and replace it by a new array
* Function will free old array and replace it by a new array with size equal to maximum size it can have
* Maximum size is the size of the input array
*/
int* newArray(int* oldArray,int* newArray, int sizeArray, int sizeFArray)
{
if (newArray == NULL) {
int* temp = malloc(sizeFArray * sizeof(int));
if (temp == NULL)
exit(1);
return temp;
} else {
memcpy(oldArray, newArray, sizeArray);
return oldArray;
}
printf("Error");
exit(1);
}
//int isAvailable(int* array , int size, int number) checks if number is available in array (return 0 if true, 1 if false)
//printArray(int* array, int size) is a simple function to print an array
void subArray(int* inputArray, int sizeInputArray)
{
int* candidate = malloc(sizeInputArray * sizeof(int));
if (candidate == NULL)
exit(1);
int sizeCandidate = 0;
int* newCandidate = malloc(sizeInputArray * sizeof(int));
if (newCandidate == NULL)
exit(1);
int sizeNewCandidate = 0;
//We will first fill the candidate
while (sizeCandidate < sizeInputArray && isAvailable(candidate, sizeCandidate, *(inputArray + sizeCandidate)) != 0) {
*(candidate + sizeCandidate) = *(inputArray + sizeCandidate);
sizeCandidate++;
}
int index = 1;
//Check all potential new candidates
//If new candidate holds more elements than the current candidate
//Current candidate will be replaced by new candidate
//Else we will redo the process and check using the next candidate if availble
for (int i = 1; i < sizeInputArray; i++) {
if(isAvailable(newCandidate, sizeNewCandidate, *(inputArray + i)) == 0) {
if (sizeNewCandidate > sizeCandidate) {
candidate = newArray(candidate, newCandidate, sizeNewCandidate, sizeInputArray);
newCandidate = newArray(newCandidate, NULL, 0, 0);
sizeCandidate = sizeNewCandidate;
sizeNewCandidate = 0;
i = ++index;
} else {
newCandidate = newArray(newCandidate, NULL, 0, sizeInputArray);
sizeNewCandidate = 0;
i = ++index;
}
} else {
*(newCandidate + sizeNewCandidate) = *(inputArray + i);
sizeNewCandidate++;
}
}
printArray(candidate, sizeCandidate);
}
I hope this code looks more compact and has clear comments:
#include <stdio.h>
int a[] = { 4, 3, 1, 3, 2, 1, 0 };
int check(int a[], int i, int j)
{
for (int k = i; k < j; k++)
for (int l = k + 1; l < j; l++)
if (a[k] == a[l])
return 0;
return 1;
}
int main()
{
int s = 0; // start position of the best candidate
int m = 1; // length of the best candidate
int n = sizeof(a) / sizeof(0); // length of the array
for (int i = 0; i < n; i++) { // for every start position
for (int j = i + m + 1; j <= n; j++) { // for every lengh if it more than the best one
if (check(a, i, j)) { // check if it contains repetitions
if (j - i > m) { // if no repetions
s = i; // update the candidate
m = j - i; // and length
}
}
else
break;
}
}
printf("{%d", a[s]);
for(int i = s + 1; i < s + m; ++i)
printf(", %d", a[i]);
printf("}\n");
return 0;
}
This works and gives the correct output.
I don't understand the complexity of the code.
#include <stdio.h>
int main()
{
// int x[] = { 4, 3, 1, 3, 2, 1, 0 };
int x[] = { 4, 3, 1, 3, 2, 5, 0 };
int offset;
int cur_offset = 0;
int max = 0;
int max_offset = 0;
for (int i = 1; i < sizeof(x) / sizeof(int); i++) {
for (int j = i-1; j >= cur_offset; j--) {
if (x[i] == x[j]) {
if (max <= i - j) {
max = i - j;
max_offset = j + 1;
} else if (max_offset == cur_offset) {
max = i - max_offset;
}
cur_offset = j + 1;
break;
}
}
}
if (max < sizeof(x) / sizeof(int) - cur_offset) {
max_offset = cur_offset;
max = sizeof(x) / sizeof(int) - max_offset;
}
printf("%d", x[max_offset]);
for (int i = max_offset + 1; i < max_offset + max; i++)
printf(", %d", x[i]);
printf("\n");
}
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.
I have written a program in C. The problem is when I compile this program in a Linux/Unix environment I get a segfault. But when I compile it in Windows with minGW It works fine. Basically in the program I have a multidimensional array. When I compile and debug in gdb in Linux/Unix I lose one row of the multidimensional array randomly. When I try to access every column in that row all of them suddenly cannot be accessed. My whole row gets lost.
Error:Program received signal SIGSEGV, Segmentation fault.
Note: isItDone(), oneToTwo(), and checkAroundTwo() are very likely not the problem. I tried running program without them and it still showed the error.
The code:
int main( int argc, char *argv[] ){
FILE * output;
output = fopen("output.txt", "w");
srand(time(NULL));
int size = 0; // Resetting before taking arguments
int evaltime = 0; // Resetting before taking arguments
int rand1, rand2;
int counter, counter2, counter3;
if(argc == 3){
size = atoi(argv[1]);
evaltime = atoi(argv[2]);
}
else{
return 0;
}
double *evaltimes = (double*)calloc(evaltime , sizeof(double)); // The array of the results we got.
for(counter2 = 0; counter2 < evaltime; counter2++){
int cellnumbers = 0;
int **ground = (int**)malloc(size * sizeof(int)); //Mallocating for every iteration
for(counter = 0; counter < size; counter++){
ground[counter] = (int*)calloc(size, sizeof(int)); // Initializing all the 0.
}
while(!isItDone(ground, size)){ // It's finished when last row is 2.
rand1 = rand() % size;
rand2 = rand() % size; // Take two random numbers for picking in array limit.
printf("%d %d\n", rand1, rand2);
if(rand1 == 0){ // Is it a top cell
if(ground[rand1][rand2] == 0){
ground[rand1][rand2] = 2;
cellnumbers++; // Increment when a cell is picked.
}
}
else{
if(ground[rand1][rand2] == 1 || ground[rand1][rand2] == 2) // The cell is already opened
continue;
else{
ground[rand1][rand2] = 1; // Defaulting to 1 before control
cellnumbers++;
oneTotwo(ground, size, rand1, rand2);
}
}
}
if(counter2 == evaltime - 1){ // Printing the last variation
for(counter3 = 0; counter3 < size; counter3++){
for(counter = 0; counter < size; counter++){
fprintf(output, "%d ",ground[counter3][counter]);
}
fprintf(output, "\n");
}
}
evaltimes[counter2] = (double)cellnumbers / (double)(size*size);
for(counter = 0; counter < size; counter++)
free(ground[counter]);
free(ground);
}
double meany = mean(evaltimes, evaltime);
double stddeviation = stddev(evaltimes, evaltime, meany);
fprintf(output, "mean() = %f \n", meany);
fprintf(output, "stddev() = %f",stddeviation);
fclose(output);
return 0;
}
I think the bug is most likely lies in main but here are my functions.
int isItDone(int **p, int size){
int counter;
for(counter = 0; counter < size; counter++){
if(p[size - 1][counter] == 2 && (p + size - 1) != 0)
return 1;
}
return 0;
}
void oneTotwo(int **p, int size, int rand1, int rand2){
//Checking the Upper Cells
if(rand1 < size - 1){ // Making sure no control if it is the last cell.
if(p[rand1 + 1][rand2] == 2){
p[rand1][rand2] = 2;
checkAroundTwo(p, size, rand1, rand2);
}
}
if(rand1 > 0){
if(p[rand1 - 1][rand2] == 2){
p[rand1][rand2] = 2;
checkAroundTwo(p, size, rand1, rand2);
}
}
if(rand2 < size - 1){
if(p[rand1][rand2 + 1] == 2){
p[rand1][rand2] = 2;
checkAroundTwo(p, size, rand1, rand2);
}
}
if(rand2 > 0){
if(p[rand1][rand2 - 1] == 2){
p[rand1][rand2] = 2;
checkAroundTwo(p, size, rand1, rand2);
}
}
}
void checkAroundTwo(int **p, int size, int rand1, int rand2){
if(rand1 < size - 1){
if(p[rand1 + 1][rand2] == 1){
p[rand1 + 1][rand2] = 2;
checkAroundTwo(p, size, rand1 + 1, rand2);
}
}
if(rand1 > 0){
if(p[rand1 - 1][rand2] == 1){
p[rand1 - 1][rand2] = 2;
checkAroundTwo(p, size, rand1 - 1, rand2);
}
}
if(rand2 < size - 1){
if(p[rand1][rand2 + 1] == 1){
p[rand1][rand2 + 1] = 2;
checkAroundTwo(p, size, rand1, rand2 + 1);
}
}
if(rand2 > 0){
if(p[rand1][rand2 - 1] == 1){
p[rand1][rand2 - 1] = 2;
checkAroundTwo(p, size, rand1, rand2 - 1);
}
}
}
double mean(double *p, int size){
double sum = 0.0000000;
int counter;
for(counter = 0; counter < size; counter++)
sum += p[counter];
return sum / (double)(size);
}
double stddev(double *p, int size, double mean){
double sum = 0.0000000;
int counter;
for(counter = 0; counter < size; counter++)
sum += sqr(((double)p[counter] - mean));
return sqrt(sum / (double)(size - 1));
}
double sqr(double x){
return x*x;
}
double sqrt(double x){
int counter = 0;
while(sqr(counter) < x){
counter++;
}
double s = counter;
for(counter = 0; counter < 50; counter++){
s = (double)1/2 * (double)(s + x/s);
}
return s;
}
Let's assume int array[10][10]
One more weird thing is that in gdb when I for example lose array[5] row I try to access it from the row before it. For example with array[4][10]. When I do it "array[4][10] = 49". Why is this? Rest is (array[4][12], array[4][13] etc.) is 0 as I specified. Why suddenly the first element of the 5th row achieved from the 4th row becomes 49 ? That I dont understand.
When you assign memory to a 2D array, you're assigning an array of pointers, each of which points to a block of memory.
This means when you do your initial malloc you need to assign ...sizeof(int*) and not ...sizeof(int).
In short, change this line:
int **ground = (int**)malloc(size * sizeof(int));
to:
int **ground = (int**)malloc(size * sizeof(int*));