C Pointer to an Array example stops working - c

I'm working on an example and my code is stopped woking when I run it.(Note that I translated the question to English so sorry for grammar mistakes.)
Here is the question:
myShrink() function's prototype is like this:
void myShrink(int *param1, const int param2);
myShrink() function should find the average of the array param1 then should increment the element by 1 if its less than average, or should decrement the element by 1 if it's more than average. param2 is a number of elements in an array.
Here is the content of the main() function:
void myStretch(int *param1, const int param2);
int main () { int myArray[] = {2, 4, 2, 4, 2, 4};
int index;
myStretch(myArray, 6);
printf("UPDATED ARRAY: ");
for(index = 0; index < 6; index++){
printf("%d\t", myArray[index]);
}
return 0;
}
---------The result when we run the program:-----
UPDATED ARRAY: 1 5 1 5 1 5
Now this was the question part what we need to is basically programming the content of myShrink() function and here is my work:
void myShrink(int *param1, const int param2)
{
int array[param2];
param1=array;//Using pointer to point elements of array
int average=0;
int i,j;
for(i=0;i<param2;i++)
{
average+=*(param1 + i);//Adding each element of array
}
average=average/param2;//Then dividing result to param2 to find average
for(j=0;j<param2;j++)
{
if(*(param1+j)<average)//if below average
{
*(param1+j)+=1;//increment
}
else if(*(param1+j)>average)//if above average
{
*(param1+j)-=1;//decrement
}
}
}
But its stops working when I run it. Where I did make mistake and how can I fix it?

Just do this:
#include<stdio.h>
void myStretch(int *param1, const int param2);
int main () { int myArray[] = {2, 4, 2, 4, 2, 4};
int index;
myStretch(myArray, 6);
printf("UPDATED ARRAY: ");
for(index = 0; index < 6; index++){
printf("\n%d\t", myArray[index]);
}
return 0;
}
void myStretch(int *param1, const int param2)
{
int average=0;
int i,j;
for(i=0;i<param2;i++)
{
average+=*(param1 + i);//Adding each element of array
}
average=average/param2;//Then dividing result to param2 to find average
for(j=0;j<param2;j++)
{
if(*(param1+j)<average)//if below average
{
(*(param1+j))+=1;//increment
}
else if(*(param1+j)>average)//if above average
{
printf("%d ",(*(param1+j)));
(*(param1+j))-=1;//decrement
}
}
}
Now first thing: your result is wrong. It should be 3 3 3 3 3 3. As the average in this case is 3 and therefore 2 will become 3 and 4 will also become 3. Secondly you don't have to assign a new array inside the function. Just do it this way. Third mistake:
*(param1+j)>average
should be replaced by
(*(param1+j))>average
and similarly for less than sign.
UPDATE: Also note that many people argue that array[param2] is legal or not. When you declare such an array they are called Variable Length Array(VLA). This is allowed in modern C compilers but older compilers like Turbo C don't allow.

In below myShrink function, after 'param1=array;' statement param1 start pointing to array which has garbage inside.
void myShrink(int *param1, const int param2){
int array[param2];
param1=array;//Using pointer to point elements of array
int average=0;
int i,j;
//debug code to shows param1 points to array which has garage inside
int index =0 ;
for(index = 0; index < 6; index++){
printf("myDebug: %d\n", param1[index]);
}
for(i=0;i<param2;i++)
{
average+=*(param1 + i);//Adding each element of array
}
average=average/param2;//Then dividing result to param2 to find average
for(j=0;j<param2;j++)
{
if(*(param1+j)<average)//if below average
{
*(param1+j)+=1;//increment
}
else if(*(param1+j)>average)//if above average
{
*(param1+j)-=1;//decrement
}
}}

Related

A function in C runs for a set of values but gives Segmentation Fault: 11 for another

I am trying to find unique non-zero intersection between two sets. I have written a program which works for some set of arrays but gives segmentation fault for some. I have been trying to figure out why but have failed, any help will be greatly valued. The thing is the functions defined (NoRep and ComEle) are working fine but are unable to return the value to the assigned pointer in the case when Seg Fault is shown. Below is the code:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int* ComEle(int ar_1[], int size_ar1, int ar_2[], int size_ar2);
int* NoRep(int a[], int l1);
int main ()
{
// Case 1: Gives segmentation fault
int A[10] = {1,1,0,2,2,0,1,1,1,0};
int B[10] = {1,1,1,1,0,1,1,0,4,0};
int *C = ComEle(A,10,B,10); printf("check complete\n");
// //Case 2: Does not give segmentation fault
// int A[4] = {2,3,4,5};
// int B[4] = {1,2,3,4};
// int *C = ComEle(A,4,B,4); printf("check complete\n");
}
//---------------- Local Functions --------------------//
int* ComEle(int ar_1[], int size_ar1, int ar_2[], int size_ar2) {
// sort of intersection of two arrays but only for nonzero elements.
int i=0, j=0, cnt1 = 0;
int temp1 = size_ar1+size_ar2;
int CE1[temp1]; for(i=0;i<temp1;i++) {CE1[i] = 0;}
/* Size of CE1 is knowingly made big enough to accommodate repeating
common elements which can expand the size of resultant array to
values bigger than those for the individual arrays themselves! */
for(i=0;i<size_ar1;i++) {
j = 0;
while(j<size_ar2) {
if(ar_1[i]==ar_2[j] && ar_1[i]!=0) {
CE1[cnt1] = ar_1[i];
cnt1++;
}
j++;
}
}
// Have to remove repeating elements.
int *CE = NoRep(CE1, cnt1);
for(i=0;i<(CE[0]+1);i++) {printf("CE:\t%d\n", CE[i]);}
printf("ComEle: %p\n",CE);
return(CE);
}
int* NoRep(int a[], int l1) {
int cnt = 0, i = 0, j =0;
int *NR; NR = (int*)calloc((l1), sizeof(int));
//int NR[l1]; for(i=0;i<l1;i++) {NR[i] = 0;}
for(i=0;i<l1;i++) {
j = 0;
while(j<i) {
if(a[i]==a[j]) {break;}
j++;
}
if(j == i) {
cnt++;
NR[cnt] = a[i];
}
}
NR[0] = cnt; // First element: # of relevant elements.
printf("NoRep: %p\n",NR);
return(NR);
}
Thanks again for your help!
Take a look at this code:
int temp1 = size_ar1+size_ar2;
int CE1[temp1]; for(i=0;i<temp1;i++) {CE1[i] = 0;}
/* Size of CE1 is knowingly made big enough to accommodate repeating
common elements which can expand the size of resultant array to
values bigger than those for the individual arrays themselves! */
for(i=0;i<size_ar1;i++) {
j = 0;
while(j<size_ar2) {
if(ar_1[i]==ar_2[j] && ar_1[i]!=0) {
CE1[cnt1] = ar_1[i];
cnt1++;
}
j++;
}
}
Here you have nested loops, i.e. a for-loop with a while-loop inside. So - in worst case - how many times can cnt1 be incremented?
The answer is size_ar1 * size_ar2
But your code only reserve size_ar1 + size_ar2 element for CE1. So you may end up writing outside the array.
You can see this very easy by printing cnt1 inside the loop.
In other words - your CE1 is too small. It should be:
int temp1 = size_ar1*size_ar2; // NOTICE: * instead of +
int CE1[temp1]; for(i=0;i<temp1;i++) {CE1[i] = 0;}
But be careful here - if the input arrays are big, the VLA gets huge and you may run in to stack overflow. Consider dynamic memory allocation instead of an array.
Besides the accepted answer: I have been missing a break statement in the while loop in ComEle function. It was not giving me the expected value of cnt1. The following will be the correct way to do it:
for(i=0;i<size_ar1;i++) {
j = 0;
while(j<size_ar2) {
if(ar_1[i]==ar_2[j] && ar_1[i]!=0) {
CE1[cnt1] = ar_1[i];
cnt1++;
break;
}
j++;
}
}
This will also do away with the requirement for a bigger array or dynamic allocation as suggested (and rightly so) by #4386427

C data format redoing

I have data stored as
float testdata3[][7] = {
{171032, 0.4448, -0.3032, -0.7655, -1.3428, 13.5803, -73.0743},
{172292, 0.0099, 0.1470, -0.7301, -17.2272, 7.0038, -11.7722},
{173547, 0.0576, 0.1333, -0.8163, -2.7847, -9.5215, 8.1177 },
...
}
where I am only interested in the second, third and fourth indexes. How can I create a function where it would return for example first, second and third index as their own table from the testdata I have.
For example
testdata_x = {0.4448, 0.099, 0.0576, ...}
testdata_y = {-0.3032, 0.1470, 0.1333, ...}
testdata_z = {-0.7655, -0.7301, -0.8163, ...}
Help would be much appreciated. I am trying to read sensor values from test data and im only interested in acceleration values in x, y and z directions.
You didn't post any code so I'm going to be a bit more vague than normal.
If we create an array of 7 elements such as: int arr[7] = {1, 2, 3, 4, 5, 6, 7};
Accessing the 2nd, third, and 4th elements is as simple as arr[1], arr[2], arr[3] respectively.
That should help with gleaning the data from the existing arrays, but as for making your new array. I don't see any reason to use a multidimensional array instead of 3 regular arrays. All you need to do from here is find out the amount of arrays in testData in order to know how much to allocate and you should be on your way.
So you want to transpose a matrix? then just iterate in the reverse order
#include <stdio.h>
int main(void)
{
double arr[][7] = {
{171032, 0.4448, -0.3032, -0.7655, -1.3428, 13.5803, -73.0743},
{172292, 0.0099, 0.1470, -0.7301, -17.2272, 7.0038, -11.7722},
{173547, 0.0576, 0.1333, -0.8163, -2.7847, -9.5215, 8.1177},
};
#define ROWS sizeof arr / sizeof arr[0]
#define COLS sizeof arr[0] / sizeof arr[0][0]
double test[COLS][ROWS]; /* 7 x 3 */
for (size_t i = 0; i < COLS; i++) {
for (size_t j = 0; j < ROWS; j++) {
test[i][j] = arr[j][i];
}
}
return 0;
}
I don't know what you are looking for but here are several approaches starting from easiest one:
1) You can directly assign a value using indexes to the new array
2) If you need function you can allocate new array inside it assign all
values and return it from a function
It's supposed that indexes never change for x,y,z.
#include <stdio.h>
#include <stdlib.h>
enum
{
X,
Y,
Z
};
float testdata3[][7] = {
{171032, 0.4448, -0.3032, -0.7655, -1.3428, 13.5803, -73.0743},
{172292, 0.0099, 0.1470, -0.7301, -17.2272, 7.0038, -11.7722},
{173547, 0.0576, 0.1333, -0.8163, -2.7847, -9.5215, 8.1177 },
};
float *get_dataa(int coordinate)
{
float *data;
switch(coordinate) {
case X:
data = malloc(sizeof(float) * 3);
data[0] = testdata3[0][1];
data[1] = testdata3[1][1];
data[2] = testdata3[2][1];
return data;
default:
return NULL;
}
}
int main(void)
{
/* first way */
float testdata_X[] = { testdata3[0][1], testdata3[1][1], testdata3[2][1] };
printf("Test number 1 for X %0.4f, %0.4f, %0.4f\n", testdata_X[0], testdata_X[1], testdata_X[2]);
/* second */
float *testdata_xX = get_dataa(X);
printf("Test number 2 for X %0.4f, %0.4f, %0.4f\n", testdata_xX[0], testdata_xX[1], testdata_xX[2]);
free(testdata_xX);
return 0;
}
output:
Test number 1 for X 0.4448, 0.0099, 0.0576
Test number 2 for X 0.4448, 0.0099, 0.0576

array address do not increment correctly in C

I am trying to make a recursive function to print the content of an array.
The main looks like this:
#include <stdio.h>
static int s_index;
int main(void) { int even[] = {2, 4, 6, 8}; s_index = 0; print(even);}
The print function looks like this:
void print(int * array) {
if(s_index > 3) {
printf("\n"); return;
}
printf(" %d ", *array); ++s_index; print(array + s_index);
}
What I notice is:
if &even is 0x7fffffffdbf0 then (array + s_index) increments as follow with s_index:
s_index = 0 : 0x7fffffffdbf0;
s_index = 1 : 0x7fffffffdbf4;
s_index = 2 : 0x7fffffffdbfc;
it should be 0x7fffffffdbf8!!?
It is blowing my mind, could someone help with that?
Thank you for your answers.
You made a logical mistake in your recursive call. See what happens:
Assume &even = 0x7fffffffdbf0
First call:
array = 0x7fffffffdbf0 ; s_index = 0.
You increase s_index and pass into the second call array + s_index, which yields:
Second call:
array = 0x7fffffffdbf4 ; s_index = 1.
Again, you increase s_index and pass into the third call array + s_index, which yields:
array = (0x7fffffffdbf4) + 2 => 0x7fffffffdbfc
You should only increase array by 1 for each recursive call, and remove s_index completely (that's the point of the recursion, to get rid of global variables)
Please get rid of the global value s_index.Change your func signature as shown below
int main(void)
{
int even[] = {2, 4, 6, 8,10,12};
print(even,(sizeof(even)/sizeof(int)));
}
void print(int * array,int len) {
if( len == 0)
{
printf("\n"); return;
}
else
{
printf(" %d ", *(array));
print(array+1,len-1);
}
}
Please don't do really strange and obscure things for no apparent reason, such as using recursion where simple loops are faster, safer and more readable. Because when you are doing really strange things on purpose, other equally strange things tend to happen unexpectedly.
#include <stdio.h>
void print(int* array, size_t size)
{
for(size_t i=0; i<size; i++)
{
printf("value:%d address:%p\n", array[i], (void*)&array[i]);
}
}
int main(void)
{
int even[] = {2, 4, 6, 8};
print(even, 4);
}

Integer array passed as a Structure variable [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 8 years ago.
Here is my code, cant figure out why the size of array is 2.
Help me out in correcting my code, so that i can get the Max() function right.
//Max() gets the max value and Min()gets min value
#include <stdio.h>
#include "conio.h"
struct test {
int input[10];//input array , I need to get out Max and min functions right
int min;
int max;
} testDB[2] =
{
{{1,2,3,4,5,6},1,6},
{{3,4,5},3,5},
};
int Max(int* input){
int max,i,size;
max = input[0];
size = sizeof(input)/sizeof(input[0]);
printf("\n-----------\n");//print debugging
printf("\t%d",size);
printf("\n-----------\n");//print debugging
for(i=0;i<size;i++)
{
if(max<input[i])
max = input[i];
printf("%d\n",max);
}
return max;
}
int Min(int*input)
{
int min,i;
min = input[0];
for(i=0;i<sizeof(input)/sizeof(input[0]);i++)
{
if(min>input[i])
min = input[i];
}
return min;
}
void testCases()
{
int max,min,i;
for(i=0; i<2; i++) {
printf("Test cases for Max\n");
max = Max(testDB[i].input);
if((testDB[i].max==max)) printf("PASSED\n"); else printf("FAILED\n");
printf("TestCases for Min\n");
min = Min(testDB[i].input);
if((testDB[i].min==min)) printf("PASSED\n"); else printf("FAILED\n");
}
}
int main()
{
testCases();
return 0;
}
This is probably it , But as a newbie I am not able to figure this thing
The reason for size of array is 2 is
look at the
} testDB[2] =
{
{{1,2,3,4,5,6},1,6},
{{3,4,5},3,5},
};
in this case, either it goes with one value from ([1,2,3,4,5,6],1,6) or it goes with the ([3,4,5],3,5).
So as it store only 2 digit the size of array is 2. as simple as that.
Megan 35 : n2KVjLKVmLKukLK7muG+lgK0lHzZlwu5

Array shows its pointer instead of its value

I'm stuck in some trouble, unfortunately I'm still learning the details of this language.
I have the following code
#define SIZE 5
typedef struct
{
int start;
int end;
int nElements;
int vetor[SIZE];
} TSTACK;
and I try to inser values in its array using the following function:
void Push(TSTACK *s, int elementInsert)
{
if(IsFull(s))
{
printf("%s\n", "# ERROR: full.");
}
else
{
s->end++;
if(s->end == SIZE)
{
s->end = 0;
}
s->vetor[s->end] = elementInsert;
s->nElements++;
}
}
and I use the following function to show elements:
void Display(TSTACK *s)
{
int i;
if (isEmpty(s))
{
printf("%s\n", "# ERROR: empty");
}
else
{
for (i = 0; i < s->nElements; i++)
{
printf ("value: %d\n", s->vetor[i]);
}
}
}
My question is that I don't get the same result when I add different amount of elements, when I insert 5 elements, the Display function display all the elements correctly, but when I insert less than 5, the first item appears to be its pointer:
The following main results in 4201166, 3, 5, 7
int main(void)
{
TSTACK test;
test.start = 1;
test.end = 0;
test.nElements = 0;
Push(&test, 3);
Push(&test, 5);
Push(&test, 7);
Push(&test, 3);
Display(&test);
}
The following main results in 5, 3, 5, 7, 3
int main(void)
{
TSTACK test;
test.start = 1;
test.end = 0;
test.nElements = 0;
Push(&test, 3);
Push(&test, 5);
Push(&test, 7);
Push(&test, 3);
Push(&test, 5);
Display(&test);
}
Can someone show me where I am wrong?
When you "insert" an element, you do it at
s->vetor[s->end]
But before you do that you increase s->end, so the first element will be at s->vetor[1]. Since the first element (s->vetor[0]) is not initialized, you will have a random value there. That is the reason you have a strange value first in the four-value insert.
When you insert a fifth value, you have the check for s->end == SIZE where you set s->end to zero, so the last value in that case will end up in the first place in the array.
The solution, that will solve both of the above problems, is to increase s->end after you assigned the value to the array.
When you print the stack:
for (i = 0; i < s->nElements; i++)
{
printf ("value: %d\n", s->vetor[i]);
}
You are starting at index 0, but your stack implementation starts at index 1, so when you have less than 5 elements the first item is not initialized. Perhaps you can fix this by changing start value to 0.
First problem: Local variables aren't initialized, they contain garbage unless you initialize them.
Second problem: You start assigning at array index 1 instead of 0. Only when you insert five elements will it work, because you check if end == SIZE and if so set end = 0, making the fift insert set the first element vetor[0].

Resources