I am currently trying to make moving average with C, and I want to send my address to the function and calculate the moving average inside the function. However, whenever I get out of the for loop inside the function, the pointer which was originally pointing at the initial array changes and I have no idea how to solve the problem. Here is my code:
include <stdio.h>
#include <stdlib.h>
#define n 10
void monAvg(const float *in, float *out, int m);
int main(int argc, char *argv[])
{
float table_in[]={1,2,3,4,5,5,4,3,2,1};
float table_out[]={0};
if (argc != 2) {
printf ("Incorrect number of program arguments");
return 0;
}
if (atof(argv[1]) < 1 || atof(argv[1]) > n)) {
printf ("Invalid program argument value");
return 0;
}
monAvg(table_in, table_out, atof(argv[1]));
return 0;
}
void monAvg(const float *in, float *out, int m) {
float temp;
int i,j;
for (i = 0; i < (n - m + 1); i++) {
temp = 0;
for (j = i; j < i + m; j++) {
temp += *(in + j);
}
*(out + i) = temp/m;
}
}
Thank you in advance.
The problem is that you have undefined behavior: your output array has one item allocated, so processing the input of size above 1 causes writes past the allocated segment of table_out.
You can fix this by sizing the array explicitly:
float table_out[sizeof(table_in)/sizeof(table_in[0])]={0};
Note: Expression sizeof(table_in)/sizeof(table_in[0]) computes the number of elements in table_in. You can use it in place of hard-coded n, which must be kept in sync with the count of table_in in order for your code to work correctly.
I tried to write a program in C that reverses all the numbers in an array, but it actually doesn't reverse anything, so I get unchanged numbers back. I guess I got something wrong with the pointers.
Here is my code:
#include <stdio.h>
void reverse(int *n) {
int number = *n, number2 = 0;
while (number!=0) {
number2 *= 10;
number2 += number % 10;
number /= 10;
}
*n = number2;
}
void ReverseDigits(int *p, int n) {
int i = 0;
while (i < n) {
reverse(&p);
p++;
i++;
}
}
int main() {
int array[3] = {123, 456, 789}, i = 0;
while (i < 3) {
ReverseDigits(array, 3);
i++;
}
return 0;
}
In ReverseDigits the variable p is an int pointer. When you do &p you'll get a pointer to int pointer. But your reverse function just expects an int pointer so your call of reverseis wrong. Simply do
reverse(p); // insteand of reverse(&p)
In main you shall not call ReverseDigits in a loop as the function already loops the array (i.e. the number of elements passed). So skip the while and simply do:
int main() {
int array[3] = {123, 456, 789};
ReverseDigits(array, 3);
return 0;
}
It seems to me that your reverse() function is "both baffling, and necessarily wrong." (Hey, don't take that personally...)
How could such a function possibly work, without being told, not only where the (array) is, but how long it is? You seem to be missing a parameter here.
Once you've settled that problem in your design, the task of "reversing" an array is simply a process of "swapping" the first-and-last elements in an algorithm that goes something like this: (pseudocode!)
function reverse( array[], array_size) {
int i = 0;
int j = array_size - 1; // since zero-based
while (i < j) { // no need to use "<=" here"
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}
I am using a recursive function (from one of the posts here) to enumerate all combinations of selecting k items out of n. I have modified this function to save and return the enumerated combinations in a 2-dimensional array (which is passed to the function as arrPtr). I call this recursive function in a for loop (from main) for different values of k (k from 1 to n-1) to generate all the combinations for any value of n and k. Now, with 'count', being defined as static integer, the function generates all the combinations for k=1 and then goes to k=2, but then stops at one point. The reason is that I'm using the variable 'count' as an index for rows in arrPtr. Since it is a static variable, it does not reset to 0 when the function is called for the other rounds (k=2,3,4 etc.). So it results in access violation for arrPtr after a certain point. When I remove 'static' for 'count', it generates all the combinations for different values of k, but only the last combination in each round is saved in arrPtr (again due to removing 'static'). How can I save each generated combination in a row in arrPtr so I can get (and return) all of the combinations saved in one place pointed to by arrPtr at the end?
I tried to pass the index for rows in arrPtr to the function using pass by reference (passing the address of the variable) but that gets into trouble when the recursive function calls itself.
I searched a lot and found similar topics here (e.g., returning arrays from recursive functions), but they are mostly for other programming languages (I only use C; not even C++). I have spent many many hours on solving this and really need help now. Thank you in advance.
int** nCk(int n,int loopno,int ini,int *a,int **arrPtr, int k)
{
static int count=0;
int total; // equal to the total number of combinations of nCk
int i,j;
total = factorial(n)/(factorial(n-k)*factorial(k));
loopno--;
if(loopno<0)
{
a[k-1]=ini;
for(j=0;j<k;j++)
{
printf("%d,",a[j]);
arrPtr[count][j]=a[j];
}
printf("count =%d\n",count);
count++;
return 0;
}
for(i=ini;i<=n-loopno-1;i++)
{
a[k-1-loopno]=i+1;
nCk(n,loopno,i+1,a,arrPtr,k);
}
if(ini==0)
return arrPtr; // arrPtr is in fact an array of pointers, where each pointer points to an array of size k (one of the combinations of selecting k out of n elements
else
return 0;
}
what i understand is
you want to calculate the combination for any value of n and k in nCk,
define a factorial() function outside and
define a combi() function ... which calculates Combination value of n and k variables
both function before defining the main() function... that way you can avoid declaration and then defining (i mean avoid extra lines of code).
here is the code for combi() function
function combi(int n , int k){
int nFact, kFact, n_kFact, p;
int comb;
nFact=factorial(n);
kFact=factorial(k);
p=n-k;
n_kFact=factorial(p);
comb= nFact / ((n_kFact) * kFact);
return comb;
}
you can call this function in your main function .... use for loop to store the combination value for relative n and k .... thus you will get what you need .... also pass pointer or
&array[0][0]
i.e. starting address for the array... so that you can access that array anywhere in the program.
hope this may help you. thanks
GCC 4.7.3: gcc -Wall -Wextra -std=c99 enum-nck.c
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Textbook recursive definition of, n-choose-k.
int nCk(int n, int k) {
assert(0 < k && k <= n);
if (k == n) { return 1; }
if (k == 1) { return n; }
return nCk(n - 1, k) + nCk(n - 1, k - 1);
}
// But you asked for a procedure to enumerate all the combinations.
void aux_enum_nCk(int n, int k, int* all, int* j, int a[], int i) {
a[i] = n;
if (i == k - 1) {
memcpy(&all[*j], &a[0], k * sizeof(int));
*j += k;
return;
}
for (int c = n - 1; c > 0; --c) {
aux_enum_nCk(c, k, all, j, a, i + 1);
}
}
void enum_nCk(int n, int k, int* arr) {
assert(0 < k && k <= n);
int j = 0;
int a[k];
for (int i = 0; i < k; ++i) { a[i] = 0; }
for (int c = n; c >= n - k - 1; --c) {
aux_enum_nCk(c, k, arr, &j, a, 0);
}
}
int main(int argc, char* argv[]) {
int n = 7;
int k = 3;
int x = nCk(n, k);
printf("%d choose %d = %d\n", n, k, x);
int arr[x][k];
enum_nCk(n, k, &arr[0][0]);
for (int i = 0; i < x; ++i) {
for (int j = 0; j < k; ++j) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
Situation
I was trying to implement a more interesting mergesort that creates a random length array with random values and then randomizes them, but after debugging and compiling it segfaults. I don't know why it segfaults, but I'm sure it's related to memory allocation.
Question
Why does this code cause a segfault?
Code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Declare some stuff up front
int array_size(int *array);
int print_array(int *array);
//Some decade old main function coming at you
int main() {
//Concerned with the integrity of my rand
srand( (unsigned)time( NULL ));
//A global, random length array between 1 and 100?
int *array;
array = malloc(sizeof(*array) * ((rand() % 100) + 1));
init_array(*array);
getchar();
return 0;
}
int init_array(int *array) {
//Base case
array[0] = 1;
//random values for i in array
int i;
for(i = 1; i <= array_size(array); i++) {
array[i] = rand() % array_size(array) + 1;
}
//randomize the random values in the random length array
for (i = 0; i < (array_size(array) - 1); i++)
{
unsigned int swapA = (rand() % array_size(array)) + 1;
int a = array[swapA];
array[swapA] = array[i];
array[i] = a;
}
//output random array, then mergeSort the array
print_array(array);
sort_array(array);
return 0;
}
//Get my array.Length
int array_size(int *array) {
return sizeof(array)/sizeof(array[0]);
}
//Output array
int print_array(int *array) {
int i;
for(i = 0; i < (array_size(array) + 1); i++) {
printf("%d\n", array[i]);
}
return 0;
}
//merge the array after sorting
void merge_array(int *array, int low, int split, int high) {
int sorted[high-low+1];
int a = 0;
int b = low;
int c = split + 1;
//iterate from beginning to middle and from middle to end in parallel
while(b <= split && c <= high)
{
if(array[b] < array[c])
{
sorted[a++] = array[b++];
}
else
{
sorted[a++] = array[c++];
}
}
while(b <= split) sorted[a++] = array[b++];
while(c <= high) sorted[a++] = array[c++];
int i;
for(i = 0; i < a; i++) {
array[i+low] = sorted[i];
}
print_array(array); //Print sorted array
}
//Sort the array
int sort_array(int *array, int low, int high) {
int split = ( low + high ) / 2;
if( low < high ) {
sort_array(array, low, split);
sort_array(array, split + 1, high);
merge_array(array, low, split, high);
}
}
return sizeof(array)/sizeof(array[0]);
The above statement evaluates to 1 (assuming sizeof(int *) = sizeof(int), as pointed out by H2CO3).
Try something like this,
int main() {
//Concerned with the integrity of my rand
srand( (unsigned)time( NULL ));
//A global, random length array between 1 and 100?
int *array;
int number_of_elements = (rand() % 100) + 1;
array = malloc(sizeof(*array) * num_of_elements);
init_array(*array, num_of_elements);
getchar();
return 0;
}
Pass the number of elements as arguments to init_array instead of calculating it every time.
This seems to be the problem:
//Get my array.Length
int array_size(int *array) {
return sizeof(array)/sizeof(array[0]);
}
You essentially return sizeof(int*)/sizeof(int), which is not what you want. This whole thing appears because arrays decay into pointers when passed to functions.
You should read the Arrays and Pointers section in the comp.lang.c FAQ for edification.
What happens when you run your program with /WALL? What warnings are being spat out? Why?
What happens when you step through your program with a debugger attached? What is the value of each variable at each line? Why?
There are several problems with your code:
You don't check the result of malloc to see if it returned NULL.
You are passing the dereference of array to init_array, i.e. you are sending the first int of the array to init_array which then promptly dereferences it. Since malloc returns garbage data, you're dereferencing a random number inside of init_array.
array_size is not magic. If you do not track the size of your arrays in C, you cannot retrospectively find out how big you wanted them to be. You need to remember the size of the array and pass it to init_array.
This question already has answers here:
Algorithm: efficient way to remove duplicate integers from an array
(34 answers)
Closed 8 years ago.
I want small clarification in array concept in C.
I have array:
int a[11]={1,2,3,4,5,11,11,11,11,16,16};
I want result like this:
{1,2,3,4,5,11,16}
Means I want remove duplicates.
How is it possible?
You can't readily resize arrays in C - at least, not arrays as you've declared that one. Clearly, if the data is in sorted order, it is straight-forward to copy the data to the front of the allocated array and treat it as if it was of the correct smaller size (and it is a linear O(n) algorithm). If the data is not sorted, it gets messier; the trivial algorithm is quadratic, so maybe a sort (O(N lg N)) followed by the linear algorithm is best for that.
You can use dynamically allocated memory to manage arrays. That may be beyond where you've reached in your studies, though.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static int intcmp(const void *pa, const void *pb)
{
int a = *(int *)pa;
int b = *(int *)pb;
if (a > b)
return +1;
else if (a < b)
return -1;
else
return 0;
}
static int compact(int *array, int size)
{
int i;
int last = 0;
assert(size >= 0);
if (size <= 0)
return size;
for (i = 1; i < size; i++)
{
if (array[i] != array[last])
array[++last] = array[i];
}
return(last + 1);
}
static void print(int *array, int size, const char *tag, const char *name)
{
int i;
printf("%s\n", tag);
for (i = 0; i < size; i++)
printf("%s[%d] = %d\n", name, i, array[i]);
}
int main(void)
{
int a[11] = {1,2,3,4,5,11,11,11,11,16,16};
int a_size = sizeof(a) / sizeof(a[0]);
print(a, a_size, "Before", "a");
a_size = compact(a, a_size);
print(a, a_size, "After", "a");
int b[11] = {11,1,11,3,16,2,5,11,4,11,16};
int b_size = sizeof(b) / sizeof(b[0]);
print(b, b_size, "Before", "b");
qsort(b, b_size, sizeof(b[0]), intcmp);
print(b, b_size, "Sorted", "b");
b_size = compact(b, b_size);
print(b, b_size, "After", "b");
return 0;
}
#define arraysize(x) (sizeof(x) / sizeof(x[0])) // put this before main
int main() {
bool duplicate = false;
int a[11] = {1,2,3,4,5,11,11,11,11,16,16}; // doesnt have to be sorted
int b[11];
int index = 0;
for(int i = 0; i < arraysize(a); i++) { // looping through the main array
for(int j = 0; j < index; j++) { // looping through the target array where we know we have data. if we haven't found anything yet, this wont loop
if(a[i] == b[j]) { // if the target array contains the object, no need to continue further.
duplicate = true;
break; // break from this loop
}
}
if(!duplicate) { // if our value wasn't found in 'b' we will add this non-dublicate at index
b[index] = a[i];
index++;
}
duplicate = false; // restart
}
// optional
int c[index]; // index will be the number of objects we have in b
for(int k = 0; k < index; k++) {
c[k] = b[k];
}
}
If you really have to you can create a new array where that is the correct size and copy this into it.
As you can see, C is a very basic (but powerful) language and if you can, use a vector to but your objects in instead (c++'s std::vector perhaps) which can easily increase with your needs.
But as long as you only use small numbers of integers you shouldn't loose to much. If you have big numbers of data, you can always allocate the array on the heap with "malloc()" and pick a smaller size (maybe half the size of the original source array) that you then can increase (using realloc()) as you add more objects to it. There is some downsides reallocating the memory all the time as well but it is a decision you have to make - fast but allocation more data then you need? or slower and having the exact number of elements you need allocated (which you really cant control since malloc() might allocate more data then you need in some cases).
//gcc -Wall q2.cc -o q2 && q2
//Write a program to remove duplicates from a sorted array.
/*
The basic idea of our algorithm is to compare 2 adjacent values and determine if they
are the same. If they are not the same and we weren't already looking previusly at adjacent pairs
that were the same, then we output the value at the current index. The algorithm does everything
in-place and doesn't allocate any new memory. It outputs the unique values into the input array.
*/
#include <stdio.h>
#include <assert.h>
int remove_dups(int *arr, int n)
{
int idx = 0, odx = -1;
bool dup = false;
while (idx < n)
{
if (arr[idx] != arr[idx+1])
{
if (dup)
dup = false;
else
{
arr[++odx] = arr[idx];
}
} else
dup = true;
idx++;
}
return (odx == -1) ? -1 : ++odx;
}
int main(int argc, char *argv[])
{
int a[] = {31,44,44,67,67,99,99,100,101};
int k = remove_dups(a,9);
assert(k == 3);
for (int i = 0;i<k;i++)
printf("%d ",a[i]);
printf("\n\n");
int b[] = {-5,-3,-2,-2,-2,-2,1,3,5,5,18,18};
k = remove_dups(b,12);
assert(k == 4);
for (int i = 0;i<k;i++)
printf("%d ",b[i]);
printf("\n\n");
int c[] = {1,2,3,4,5,6,7,8,9};
k = remove_dups(c,9);
assert(k == 9);
for (int i = 0;i<k;i++)
printf("%d ",c[i]);
return 0;
}
you should create a new array and you should check the array if contains the element you want to insert before insert new element to it.
The question is not clear. Though, if you are trying to remove duplicates, you can use nested 'for' loops and remove all those values which occur more than once.
C does not have a built in data type that supports what you want -- you would need to create your own.
int a[11]={1,2,3,4,5,11,11,11,11,16,16};
As this array is sorted array, you can achieve very easily by following code.
int LengthofArray = 11;
//First elemnt can not be a duplicate so exclude the same and start from i = 1 than 0.
for(int i = 1; i < LengthofArray; i++);
{
if(a[i] == a[i-1])
RemoveArrayElementatIndex(i);
}
//function is used to remove the elements in the same as index passed to remove.
RemoveArrayElementatIndex(int i)
{
int k = 0;
if(i <=0)
return;
k = i;
int j =1; // variable is used to next item(offset) in the array from k.
//Move the next items to the array
//if its last item then the length of the array is updated directly, eg. incase i = 10.
while((k+j) < LengthofArray)
{
if(a[k] == a[k+j])
{
//increment only j , as another duplicate in this array
j = j +1 ;
}
else
{
a[k] = a[k+j];
//increment only k , as offset remains same
k = k + 1;
}
}
//set the new length of the array .
LengthofArray = k;
}
You could utilise qsort from stdlib.h to ensure your array is sorted into ascending order to remove the need for a nested loop.
Note that qsort requires a pointer to a function (int_cmp in this instance), i've included it below.
This function, int_array_unique returns the duplicate free array 'in-place' i.e. it overwrites the original and returns the length of the duplicate free array via the pn pointer
/**
* Return unique version of int array (duplicates removed)
*/
int int_array_unique(int *array, size_t *pn)
{
size_t n = *pn;
/* return err code 1 if a zero length array is passed in */
if (n == 0) return 1;
int i;
/* count the no. of unique array values */
int c=0;
/* sort input array so any duplicate values will be positioned next to each
* other */
qsort(array, n, sizeof(int), int_cmp);
/* size of the unique array is unknown at this point, but the output array
* can be no larger than the input array. Note, the correct length of the
* data is returned via pn */
int *tmp_array = calloc(n, sizeof(int));
tmp_array[c] = array[0];
c++;
for (i=1; i<n; i++) {
/* true if consecutive values are not equal */
if ( array[i] != array[i-1]) {
tmp_array[c] = array[i];
c++;
}
}
memmove(array, tmp_array, n*sizeof(int));
free(tmp_array);
/* set return parameter to length of data (e.g. no. of valid integers not
* actual allocated array length) of the uniqe array */
*pn = c;
return 0;
}
/* qsort int comparison function */
int int_cmp(const void *a, const void *b)
{
const int *ia = (const int *)a; // casting pointer types
const int *ib = (const int *)b;
/* integer comparison: returns negative if b > a
and positive if a > b */
return *ia - *ib;
}
Store the array element with small condition into new array
**just run once 100% will work
!)store the first value into array
II)store the another element check with before stored value..
III)if it exists leave the element--and check next one and store
here the below code run this u will understand better
int main()
{
int a[10],b[10],i,n,j=0,pos=0;
printf("\n enter a n value ");
scanf("%d",&n);
printf("\n enter a array value");
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);//gets the arry value
}
for(i=0;i<n;i++)
{
if(check(a[i],pos,b)==0)//checks array each value its exits or not
{
b[j]=a[i];
j++;
pos++;//count the size of new storing element
}
}
printf("\n after updating array");
for(j=0;j<pos;j++)
{
printf("\n %d",b[j]);
} return 0;
}
int check(int x,int pos,int b[])
{ int m=0,i;
for(i=0;i<pos;i++)//checking the already only stored element
{
if(b[i]==x)
{
m++; //already exists increment the m value
}
}
return m;
}