C array elements change value - c

I define three arrays. Once the first one is allocated, I print out its first element which is as expected. Then, a second array ('problematic') is allocated. When I reprint the first array's first element, it has magically changed to the value I allocated the array 'problematic' with. It gets even weirder. Had I chosen not to allocate the array 'problematic' but 'working' between the two print statements, everything works fine.
What's going on?
#include<stdio.h>
int problem(double variable);
int main(){
problem(1.0);
return 0;
}
int problem(double variable){
int limit1 = 10;
int limit2 = 10;
double bin_bounds[limit1];
double problematic[limit2];
double working[limit2];
// Allocate first array
for (int bin=0; bin<limit1; bin++){
bin_bounds[bin] = variable/limit1 * (bin+1);
}
printf("%f\n\n",bin_bounds[0]); // prints 0.2 as excpected
for (int el=0;el<=limit2;el++){problematic[el]=2.;}
printf("%f\n\n",bin_bounds[0]); // prints 2.0
return 0;
}

It's array out of bound, you are allocating 10 elements with index 0 to 9 but you're accessing index 10. Your loop should only be
for (int el=0;el<limit2;el++){problematic[el]=2.;}
The big_bounds is probably allocated right after the problematic in this case. So problematic[10] is at the same memory address as big_bounds[0]

Run with valgrind and check whether you are accesing invalid memory.During declaring array init it with 0.

Related

Determinant of the matrix — recursive function

I wrote a program which returns a determinant of a matrix. I have a problem, actually; it always returns the "0" value. I notice that my determinant always stays as 0 even though I add numbers to it.
I wrote an English translation in the comments to understand my program better. I use a method in which we select one number and then crossed the element from the column and line of the selected number and then calculate the determinant of the uncrossed elements.
#include<stdio.h>
#include<stdlib.h>
float wznmacierz(float*macierz, int rozmiar)/*"macierz" means a matrix and "rozmiar" is a size of matrix */
{
if (rozmiar == 1)
return *macierz;
float *podmacierz = malloc((rozmiar-1)*(rozmiar-1)*sizeof(float)); // making a second matrix for uncrossed elements.
int wyznacznik = 0; // wyznacznik is the determinant of matrix
for(int element_S = 0; element_S <rozmiar; element_S++) //element s is a number from first line
{
for (int w = 1 ; w < rozmiar; w++ ) //line of checking element
{
for(int kolumna = 0; kolumna < rozmiar; kolumna++)//column of chcecking element
{
if(kolumna == element_S)
continue;
*podmacierz = macierz[(rozmiar*w)+(kolumna)];
podmacierz++;
}
}
wyznacznik += macierz[element_S]*( element_S % 2 ? -1: 1)* wznmacierz(podmacierz, rozmiar-1);
}
return wyznacznik;
}
void main()
{
float a[2][2]={{1,3},{9,8}};
printf("%d", wznmacierz(a,2));
}
Change void main to int main, because main returns an int.
In printf("%d", wznmacierz(a,2)); , change %d to %g, because %d is for formatting an int, but wznmacierz returns a float. %g will format a float. Also add \n after %g to complete the line being output.
In printf("%d", wznmacierz(a,2));, change a to *a because wzmacierz expects a pointer to a float, not a pointer to an array of float. This is a kludge to get your program “working” quickly; see Notes below.
You cannot use podmacierz both to hold the start address of the allocated array and to increment to places within the array. Inside the loop on element_S, put float *p = podmacierz; to make a second pointer, and change the uses of podmacierz inside that loop to p.
Before returning from the function, use free(podmacierz); to release the allocated space.
Notes
In main, a is declared as float a[2][2]. This makes it an array of 2 arrays of 2 float. In the call wznmacierz(a,2), a is automatically converted to a pointer to its first element. That produces a pointer to an array of 2 float. However, wznmacierz is declared with a parameter float*macierz, which is a pointer to a float.
One way to fix this is to pass *a. Once a is converted to a pointer to its first element, a pointer to an array of float, then applying * produces the thing that pointer points to, an array of float. Then that array of float is automatically converted to a pointer to its first element, producing a pointer to a float. You could also write wznmacierz(&a[0][0], 2).
This produces a pointer of the correct type for wznmacierz, which then access the array by calculating element locations, using macierz[(rozmiar*w)+(kolumna)]. This nominally calculates correct addresses for the array elements, since arrays are laid out in memory contiguously, but it is bad style unless necessary, and some people might consider it not to conform to the C standard in a pedantic sense.
One fix would be to define a in main as float a[2*2] = {1, 3, 9, 8};. Then the matrix is implemented as single flat array of float everywhere it is used.
Another fix would be to upgrade wznmarcierz to use two-dimensional arrays. A number of changes are needed to do this. I have not tested them, but I think they are at least:
Change wznmacierz(a,2) to wznmacierz(2, a).
Change the declaration of wznmacierz to float wznmacierz(int rozmiar, float macierz[rozmiar][rozmiar]).
Change the use of macierz inside the function from macierz[(rozmiar*w)+(kolumna)] to macierz[w][kolumna].
Change float *podmacierz = malloc((rozmiar-1)*(rozmiar-1)*sizeof(float)); to float (*podmacierz)[rozmiar-1] = malloc((rozmiar-1) * sizeof *podmacierz);.
Remove the float *p = podmaciarz; that I told you to insert above.
Inside the loop using w, insert float *p = podmacierz[w];.
Change macierz[element_S] to macierz[0][element_S].
Change wznmacierz(podmacierz, rozmiar-1) to wznmacierz(rozmiar-1, podmacierz).

dynamically storing prime numbers in a 1d array

I am making a program which stores prime numbers in a given range into an 1-d array dynamically. I have read about dynamic memory allocation in c,but i don't know what's wrong with my code.
Initially I define an "isprime" function which checks whether a number is prime or not and if the number is prime it returns 1.
After that I use a for loop which helps in storing of prime numbers in an array.
In the for loop I use an if statement which checks whether the number in the range input by the user is prime or not,and if it is prime it is stored in an array p for which memory is allocated dynamically using malloc.
But in the array p no prime numbers are stored and instead garbage values are stored,I don't know why prime numbers are not getting stored in my array?
#include<stdio.h>
#include<math.h>
int isprime(int n)
{
int i;
for(i=2;i<sqrt(n);i++)
{
if(n%i==0)
{
return 0;
}
}
return 1;
}
main()
{
int *p,i,n,j=1;
scanf("%d",&n);
for(i=0;i<n;i++)
{
if(isprime(i)&&i!=0&&i!=1)
{
p=malloc(j*sizeof(int));//Memory allocation for p should increase as more prime no.s are stored
p[j-1]=i;
j++;
}
}
printf("%d\n",p[1]);//garbage value is printed instead of any prime no.
}
malloc will return a new memory region each time in your loop, losing your previous data.
You need realloc instead
int *p = NULL; // initialize to NULL
and in the loop:
p=realloc(p,j*sizeof(int));
so either p address is kept and memory increased, either previous data from p is copied and a new p is issued. Either way it's transparent for you.
(First time, as p is NULL, it acts like malloc)
Note that it's rather inefficient to realloc at each iteration. It would be better to resize less often, and keep record of capacity and actual data length. For instance like this:
Init:
int growth = 100;
int capacity = 0;
int *p = NULL;
and in the loop:
if (j>=capacity)
{
capacity += growth;
p = realloc(p,capacity*sizeof(int));
}
Aside: as comments noted, for the answer to full work, don't omit last value when checking for primes or you'll detect perfect squares as primes.

Changing size of 2d array on iteration

Im new to C coding. In order to learn the language i want to do following little "program".
I want to scan inputs , and put them into 2d array - but i do now know how many elements i want to scan / input = i want to dynamicly create 2d array. And here is the problem. I know how i can dynamicly create 1d array e.g
int MAX;
int *arr;
scanf("%d",&MAX);
arr=(int*)malloc( Max * sizeof ( int ) )
i found how to allocate 2d array e.g
int X;
int Y;
int **arr;
scanf("%d%d",&X,&Y);
arr=(int*) malloc ( X * Y * sizeof ( int* ) )
But i havent found the thing i need the most = create 2d array and increase its " memory or size " every time new item is being added.
For example - what i would like to achieve.
int **arr;
int index=1;
int X;
int Y;
arr=(int *) malloc ( index * sizeof ( int ) );
while (! feof ){
scanf("%d%d",&X,&Y);
if ( index > 1 ){
index ++;
arr=realoc( arr*, index * sizeof ( arr* ) )
arr[iX][0]=X;
arr[iX][1]=Y;
} else{
arr[iX][0]=X;
arr[iX][1]=Y;
index++;
}
}
this was my attempt and i failed horribly.. how can dynamicly change size of 2d array on every input (or every iteration of loop )
i am aware of this solution but all answer are used with predefined y-osis of array. e.g arr[][25]
First you need a field of pointers, each pointer in the field of pointers points to the first element of a row/column of your matrix. Each time you want to add a value to your row/column you have to increase your row/column with realloc. Each time you want to add a new row/column you have to add one pointer to your field of pointers. Thus you need two conditions of truncation, one for the row/column and one for the field of pointers.
The following code shows an example how that can be realized. However be aware that the program may terminate due to allocation errors.
#include <stdio.h>
#include <stdlib.h>
main(){
//numberofrows points to the pointers used for the columns countrows tells us how many pointers we have
char **numberofrows;
int countrows=0;
//countcolumns tells us how much memory has to be allocated for the current column
int countcolumns=0;
numberofrows=malloc(sizeof(char*));
//t is needed for the first run of the loop otherwise the program will likely terminate
int t=0;
//truncation condition: e signals the end of the usersinput
while(t==0||numberofrows[countrows-1][countcolumns-1]!='e'){
countcolumns=0;
countrows++;
t=0;
//allocation of new array and reallocation of pointer array
numberofrows[countrows-1]=malloc(sizeof(char));
*numberofrows=realloc(*numberofrows,sizeof(char*)* countrows);
//truncation condition \n: end of current column, condition e: end of input for 2d array
while(t==0||(numberofrows[countrows-1][countcolumns-1]!='\n'&&numberofrows[countrows-1][countcolumns-1]!='e')){
countcolumns++;
//change for t to activate truncation conditions
t=1;
// info for what postion new value is needed realloc to make place for additional value and setting of new value
printf("row: %d, column: %d\n",countrows,countcolumns);
numberofrows[countrows-1]=realloc(numberofrows[countrows-1],sizeof(char)*countcolumns);
numberofrows[countrows-1][countcolumns-1]=getchar();
//clears input buffer
if(numberofrows[countrows-1][countcolumns-1]!='\n')
while(getchar()!='\n'){}
}
}
//prints transposed 2d array
int tc=0,k=0;
while(tc<countrows){
k=0;
while(numberofrows[tc][k]!='\n'&& numberofrows[tc][k]!='e'){
printf("%c ",numberofrows[tc][k]);
k++;
}
printf("\n");
tc++;
}
}

How to correctly compare and print out matching elements in this array in C?

I have this simple problem to which I am trying to write a solution, in C.
If an array arr contains n elements, then write a program to check
if arr[0] = arr[n-1], arr[1] = arr[n-2] and so on.
And my code looks like this-
#include<stdio.h>
int main()
{
int arr[10],i=0,j;
int k=0;
printf("\n Enter 10 positive integers: \n");
for(k=0;k<=9;k++)
scanf("%d",&arr[k]);
while(i<=9)
{
for(j=9;j>=0;j--)
{
if(arr[i]==arr[j])
{
printf("\n The array element %d is equal to array element %d\n", arr[i],arr[j]);
}
i++;
continue;
}
}
return 0;
}
On entering this input-
Enter 10 positive integers:
10
20
30
40
50
60
40
80
20
90
The output I get is-
The array element 20 is equal to array element 20
The array element 40 is equal to array element 40
The array element 40 is equal to array element 40
The array element 20 is equal to array element 20
Now, there are two problems with this code-
As you can see, the program prints out matching array elements twice. This is because, the way I've structured the program, once the variable i loops through the array from the first to last element, and then j loops through from the last to first element. So each prints out the matching array element once, leading to two sets of values.
My second question is- In my code, I've hard-coded the length of the array in the for loops(0 to 9 for an array of 10 elements). What change can be done so that the length of the array, as entered by the user, can directly be used in the for loops?
I've read that, in C, array dimensions(when declaring) cannot be a variable. So, a declaration like this(which was my first thought) wouldn't work-
int n; // n is no. of elements entered by the user
int arr[n];
I'm a newbie to programming, so my apologies if the question sounds/is too simple, low-quality.
Thank You.
1)You can traverse the array for half times for getting the prints only once. Instead of for(j=9;j>=0;j--) you can use for(j=9;j>=9/2;j--).
2)
int n;
int arr[n].
Recent Compilers support this statement. If you don't like to use this, you can go for dynamic memory allocation for the array.
My second question is- In my code, I've hard-coded the length of the array in the for loops(0 to 9 for an array of 10 elements). What change can be done so that the length of the array, as entered by the user, can directly be used in the for loops?
Use dynamic memory allocation. Use malloc().
So code will be
{
int num_elements;
int* arr;
printf("Enter number of elements\n");
scanf("%d", &num_elements);
arr = (int *) malloc(num_elements * sizeof(int)); // Use this 'arr' for holding input data from user
// Your remaining code comes here
free(arr); // Free the pointer in the end of program
}
the variable length creation works for me:
#include<stdio.h>
int main(){
int a, i;
scanf("%i", &a);
int blah[a];
for (i = 0; i < a; i++){
printf("/n%i", blah[a]);
}
}
The other way would be to create the maximum length array and than simply use first n elements.
As the previous answer states it is up to you to make sure you are checking each element only once therefore stopping at the element n/2. It is probably important that n/2 is rounded to the closest smaller integer, so at first glance odd numbers of arguments may be differently handled. But as it is omitting only the middle element it is identical to itself.
For your first query
for(i=0;i<n/2;i++)
{
if(a[i]==a[n-(i+1)])
{
printf("\n The array element %d is equal to array element %d\n",a[i],a[n-(i+1)]);
}
}
For your second query you can use condition i<(n/2) (which runs the loop (n/2)-1 times) For your case where n = 10 it will run from 0 to 4.
If you want to loop from 0 to 9 you can use
for(i=0;i<n;i++)
For making array of n elements where n is a variable either make an array of elements that is always greater than n or do it by making a dynamic array.
http://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html
corrected:
#include<stdio.h>
int main()
{
int i=0, size; // size of array
int k=0; // counter
printf("enter size of array\n");
scanf("%d", &size); // ask user for desired size
int *arr = malloc(size * sizeof(int)); // allocate memory for array
printf("\n Enter 10 positive integers: \n"); // fill your array of size size
for(k=0;k<size;k++)
scanf("%d",&arr[k]);
k = 0; // reset this counter
for(i=0; i<size/2; i++) // check only for half of it
{
if(arr[i] == arr[size-i-1]) // try it with paper and pincil
{
printf("match arr[%d]=arr[%d]=%d\n", i,size-i-1, arr[i]);
k++;
}
}
if(k==0) printf("No matching");
return 0;
}

int* vector accepts only the first given value

I'm experiencing some troubles with my code written in C. It's all about an int * vector intially declared and dynamically allocated but when it comes to filling it with data it stuck on the first element and won't increment the counter to fill the rest of the vector
my header file : instance.h
struct pbCoupe
{
int tailleBarre;
int nbTaillesDem;
int nbTotPcs;
int * taille;
int * nbDem;
};
my code : coupe.c
pb->taille = (int*) malloc (pb->nbTaillesDem * sizeof(int));
pb->nbDem = (int*) malloc (pb->nbTaillesDem * sizeof(int));
while (i < pb->nbTaillesDem)
{
fscanf_s(instanceFile,"%s",data,sizeof(data));
pb->taille[i] = atoi(data); //<-- here is the problem !! it only accept the first value and ignore all the rest
printf("%s\n",data);
fscanf_s(instanceFile,"%s",data,sizeof(data));
pb->nbDem[i] = atoi(data); //<-- the same problem here too !!
printf("%s\n",data);
i++;
}
Your interpretation of sizeof is wrong, since data is the buffer that the string is being parsed into.
It returns the size of the the variable, not the size of the the what the variable (or namely a pointer) points to
Strings in C are all pointer to the size would be 4 bytes on a 32-bit system, 8 on a 64-bit.
Since it prints all the number it reading more numbers that intended with each loop iteration 4 bytes = 4 characters, atoi on parses the first integer and returns,
EDIT: If it is a buffer array, sizeof returns the size of the array.
You need to make sure you are only reading in a single number per iteration of the loop to solve this issue.
If you don't care for the literal string, best thing you can do is use:
fscanf(instanceFile, "%d", ((pb->taille) + i)));
//and store the integer into the index right away
//last param same as &pb->taille[i]

Resources