I have an array with values initialized to an integer value. When I try to change the values and print to file, the code compiles but returns a "segmentation fault" error upon execution. Any thoughts would be much appreciated!
int theArray[50];
...//code setting the array values to zero
int i;
for(i = 0; i < 50; i++)
{
...//code setting int "p" to some number between -100 and 100
if (p < 25 || p > -25)
{
int temp = p + 25;
int currentVal = theArray[temp];
theArray[temp] = currentVal + 1;
}
}
When I take out the step changing the "currentVal" there is no segmentation fault. Thanks in advance!
Your condition is wrong
if (p < 25 || p > -25)
if p is 1000, it will enter this if, as well as when p is -1000. You need the AND logical operator
if (p < 25 && p > -25)
Also, since your valid indices range from 0 to 49 inclusive, I think one of the operators must include equality, namely:
if (p < 25 && p >= -25)
You've never declared the size of the array, so it's an array of length 0 (no ints have been allocated). Therefore, then you try to initialize a part of the array, you get a segmentation fault due to accessing memory in which you are not allowed to.
To fix this, give the array a compile-time constant array size:
int theArray[50];
...//code setting the array values to zero
int i;
for(i = 0; i < 50; i++)
{
int currentVal = theArray[i]; // make sure you've initialized the array before doing this
theArray[i] = currentVal + 1;
}
While giving the input you must have entered integers more than the size of your array theArray[] i.e, 50.That is why your compiler is showing you segmentation fault.
I am almost sure it be if(p<25 && p>-25)... You probably confused the logical operators.
Isn't this is what you are trying to do ?
int i;
for(i = 0; i < 50; i++) {
theArray[i] += 1;
}
Does this not work for you ?
EDIT
if (p < 25 || p > -25) will evaluate to true for values such as -50, -26, etc because of short circuit evaluation of ||, meaning p < 25 will be evaluated first and if found true the other condition will not be evaluated.
For numbers like 50, the second condition will evaluate to true and temp will again go out of bounds for theArray
In either case, you will see Segmentation fault
if (p < 25 && p > -25) should help you.
Related
I have an allocated array and need to go over all fields and compare non null values. Values in this array can also be 0 which is causing some trouble for me.
int size = 4;
int *numbers = (int*) malloc(size * 4);
// Fill some fields
numbers[0] = 3;
numbers[1] = 0;
numbers[2] = 6;
// Search and find min value's index
int min = 0;
for (int i = 0; i < size; i++) {
if (numbers[i] != NULL) {
if (numbers[i] < numbers[min]) min = i;
} else {
// Code if value is null here
}
}
printf("%d\n", min);
Im not sure how to compare properly with NULL. What is the correct way?
Your overall design is flawed. You should not treat NULL as a catch-all zero value. NULL is a special pointer value, not simply an integer. If you compare an int against NULL, you're comparing two different types, which is not a good idea. Furthermore, you're comparing a scalar type with a pointer type, which is even worse.
Values in this array can also be 0 which is causing some trouble for me.
If this is the case, you cannot use 0 as both a value and a "mark" for "non present value". Problem is, you cannot use NULL either, because it's a different type. If you try using it, the compiler will warn you (or at least it should, if you enable warnings). At best, assigning NULL will implicitly convert it to int and result in 0 since NULL is usually defined just as ((void *)0), so it will be impossible to distinguish between NULL-ed values and valid values.
You will have to reserve one of the values between INT_MIN and INT_MAX for this purpose:
#include <limits.h>
enum { NOT_PRESENT = INT_MIN };
int size = 4;
int *numbers = malloc(size * sizeof(int));
// Initialize all to NOT_PRESENT
for (int i = 0; i < size; i++)
numbers[i] = NOT_PRESENT;
// Fill some fields
numbers[0] = 3;
numbers[1] = 0;
numbers[2] = 6;
// Search and find min value's index
int min = 0;
for (int i = 0; i < size; i++) {
if (numbers[i] != NOT_PRESENT) {
if (numbers[i] < numbers[min]) min = i;
} else {
// Code if value is not present here
}
}
printf("%d\n", min);
Your allocated array elements will never be NULL. Even the memory that is freed from using free function is not NULL. IT can points to anything may be any ur own program address space or outside address space.
Ur code looks OK. The value that u did not assigned to element at index 3 can have garbage but not NULL
I have got an assignment and i'll be glad if you can help me with one question
in this assignment, i have a question that goes like this:
write a function that receives an array and it's length.
the purpose of the function is to check if the array has all numbers from 0 to length-1, if it does the function will return 1 or 0 otherwise.The function can go through the array only one.
you cant sort the array or use a counting array in the function
i wrote the function that calculate the sum and the product of the array's values and indexes
int All_Num_Check(int *arr, int n)
{
int i, index_sum = 0, arr_sum = 0, index_multi = 1, arr_multi = 1;
for (i = 0; i < n; i++)
{
if (i != 0)
index_multi *= i;
if (arr[i] != 0)
arr_multi *= arr[i];
index_sum += i;
arr_sum += arr[i];
}
if ((index_sum == arr_sum) && (index_multi == arr_multi))
return 1;
return 0;
}
i.e: length = 5, arr={0,3,4,2,1} - that's a proper array
length = 5 , arr={0,3,3,4,2} - that's not proper array
unfortunately, this function doesnt work properly in all different cases of number variations.
i.e: length = 5 , {1,2,2,2,3}
thank you your help.
Checking the sum and product is not enough, as your counter-example demonstrates.
A simple solution would be to just sort the array and then check that at every position i, a[i] == i.
Edit: The original question was edited such that sorting is also prohibited. Assuming all the numbers are positive, the following solution "marks" numbers in the required range by negating the corresponding index.
If any array cell already contains a marked number, it means we have a duplicate.
int All_Num_Check(int *arr, int n) {
int i, j;
for (i = 0; i < n; i++) {
j = abs(arr[i]);
if ((j >= n) || (arr[j] < 0)) return 0;
arr[j] = -arr[j];
}
return 1;
}
I thought for a while, and then i realized that it is a highly contrained problem.
Things that are not allowed:
Use of counting array.
Use of sorting.
Use of more than one pass to the original array.
Hence, i came up with this approach of using XOR operation to determine the results.
a ^ a = 0
a^b^c = a^c^b.
Try this:
int main(int argc, char const *argv[])
{
int arr[5], i, n , temp = 0;
for(i=0;i<n; i++){
if( i == 0){
temp = arr[i]^i;
}
else{
temp = temp^(i^arr[i]);
}
}
if(temp == 0){
return 1;
}
else{
return 0;
}
}
To satisfy the condition mentioned in the problem, every number has to occour excatly once.
Now, as the number lies in the range [0,.. n-1], the looping variable will also have the same possible range.
Variable temp , is originally set to 0.
Now, if all the numbers appear in this way, then each number will appear excatly twice.
And XORing the same number twice results in 0.
So, if in the end, when the whole array is traversed and a zero is obtained, this means that the array contains all the numbers excatly once.
Otherwise, multiple copies of a number is present, hence, this won't evaluate to 0.
When attempting this (code below), the console doesn't even request an input value, then spits out a random number (likely from a number previously stored at the location).
Why does this not work and how can i fix it?
int main( ) {
int arr[3];
for(int i = sizeof(arr); i <= 0; i--) {
scanf("%d", &arr[i]);
}
printf("%d", arr[2]);
return 0;
}
There are two things that are wrong.
Assuming you want the number of elements in the array, it is done, using:
size_t len = sizeof(arr) / sizeof(*arr)
sizeof gives the actual size (number of bytes allocated for arr.
You should start with len - 1 and not len.
NOTE: Array indexing is 0 based not 1 based, so the array elements are indexed from 0 to 2 But you would have tried to access arr[3], which can result in undefined behaviour.
You wrote i <= 0. So, i starts from let's say 2, is 2 <= 0 ? NO!
Hence it will never go inside the loop. The correct condition is i >= 0
int len = sizeof(arr) / sizeof(*arr);
for(int i = len - 1; i >= 0; i--)
Well, I don't know why you are taking reverse order input, but a general convention is to take input using:
size_t len = sizeof(arr)/sizeof(*arr);
for (i = 0; i < len; i++)
{
// take input
}
EDIT:
From other comments it seems that you don't understand the for loop.
Have a look in this answer
Please comment for any further clarification.
i <= 0
the code can never enter the loop since the initial value of i is greater than zero.
It is important to note that in C, other than languages like Java/Python, you must explicitly know the length of the array, sizeof will NOT give you the amount of items in the array.
int main() {
int arr[3];
int itemsInArray = 3;
for(int i = itemsInArray-1; i >= 0; i--) {
scanf("%d", &arr[i]);
}
printf("%d", arr[2]);
return 0;
};
Since i-- will decrease the value of i , and the condition for loop is i <=0 to start the loop the i must be 0 or negative.Since arr[3] will return 12(3 elements and each has 4 bytes(int has 4 bytes)), the value will be posivite,greater than 0 so we need to change the loop condition to check if i is positive
#include <stdio.h>
int main( ) {
int arr[3]={0};
int i = sizeof(arr)/sizeof(arr[0]) -1;
for(; i >= 0; i--) {
scanf("%d", &arr[i]);
}
printf("%d", arr[2]);
return 0;
}
There are a couple of issues with your code: first of all, sizeof(arr) won't return "3" as you probably thought; "arr" is a pointer to arr[0], so you are requesting the size of an int pointer.
Secondly, i <= 0 prevent the loop to even be executed.
Finally, please set array to zero while declarating, as best practice, ie:
int arr[3] = {0};
EDIT: i wrong-spelled my thoughts: you are requesting the size of the whole memory area allocated for the array.
Comments below are corrected though.
Every time I find a pretty good solution to a problem at my work, always start coding in C to ruin that feeling... :D
So here I am, noobing with some easy C code and wonder why it's not working o.O
I want to represent a matrix with a 2D array (array of arrays) and fill it from a text file. The code is bad, the code ugly... I'm interested any tip/trick what I can fetch from you, Mr. senior :)
What wrong with my logic? What is under the hood? Am I using the [] operator not as expected? Am I just simply don't know how to iterate through a 2D array? I complie this source on windows with cl, using declaration in for() and god know what else what is not strictly C-like.
Input is a text file containing the size of the matrix and the elements of it separated by white space(s). The syntax of this: file := {n, A | n :-N, A := N^(n*n)}
For example:
3
1 3 2
4 5 2
7 0 1
So here it is... take cover!
#include <stdio.h>
int main(int argc, char **argv) {
Opening the file, no error checking for the minimal code :)
FILE *fp = fopen("mat_mul.test", "r");
Now, allocating the arrays based on the first integer in the file... Is this correct? Are there any better approach for allocating array of arrays?
int n = fgetc(fp) - '0';
int **A = (int**) malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++)
A[i] = (int*) malloc(sizeof(int) * n);
Aaand, here is the magic, the spell what has turned against its master :D
char act;
int i = 0, j = 0;
while (EOF != (act = fgetc(fp)))
if ('0' <= act && '9' >= act)
A[j == n - 1 ? i++ : i][j == n - 1 ? j = 0 : j++] = act - '0';
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("A[%i][%i]=%i\n", i, j, A[i][j]);
}
}
Cleaning without exhaustive!
if (fclose(fp)) {
return 0;
}
You invoke undefined behaviour when you try to do the row and column assignment and advancement at once here:
A[j == n - 1 ? i++ : i][j == n - 1 ? j = 0 : j++] = act - '0';
You assign to j in the second pair of brackets and also access its value in the first pair. (My compiler warns me that the "operation on 'j' may be undefined".) There is a sequence point between the parts of the ternary operatoy, but not between the two index operators [].
Besides the undefined behaviour, the expression is also needlessly complicated in my opinion. Separate assignmemt and advancing the row and columns counter:
if ('0' <= act && '9' >= act) {
A[i][j] = act - '0';
j++;
if (j == n) {
j = 0;
i++;
if (i == n) break; // end outer while
}
}
You should also include <stdlib.h> for the declaration of malloc. (That's also something my compiler tells me when warnings are enabled.)
so my requirements are
REQUIRES: n >= 1. Elements a[0] ... a[n-1] exist.
PROMISES
The return value is 1 if n == 1.
If n > 1, the return value is 1 if a[0] ... a[n-1] form
an arithmetic sequence.
PROMISES
Otherwise, the return value is 0.
my function so far is
int is_arith_seq(const int *a, int n)
{
assert(n >= 1);
if (n == 1)
return 1;
int i;
int initaldif = a[1]-a[0];
int currentdif,result;
for (i=0;i<n;i++)
{
currentdif = a[i+1]-a[i];
if(initaldif!=currentdif)
return 0;
}
return 1;
}
My code does not work,as I am completely stuck now, what can I do to correct it.
If array has n elements your for loop will cause a segmentation fault. It goes all the way to n-1 but you are accessing a[i+1]. a[n] is out of bounds. Modify like this :
for (i = 0; i < n - 1; i++)
{
currentdif = a[i+1]-a[i];
if (initaldif != currentdif)
return 0;
}
Problem is here
currentdif = a[i+1]-a[i];
What do you think will happen to this code during n-1 th iteration?
i = n-1 + 1 = n
Therefore the function either returns 1 if n=1 or returns 0 due to the error!
Off-by-one errors are one of the most common programming mistakes. A good way to quickly track many of these down is to look at the very first and last iterations of your loops.
Your intent is that your loop computes the differences
a[1]-a[0] a[2]-a[1] ... a[n-1]-a[n-2]
The first iteration has i=0 and computes a[1]-a[0], and the last iteration has i=n-1 and computes a[n]-a[n-1]. Whoops, that's wrong! Need to adjust the loop.
Your arithmetic sequence test should set the initialdif as you have done, but then predict what the next element is throughout the sequence. If any term fails, the string of numbers is not an arithmetic sequence:
int initaldif = a[1]-a[0];
for (i = 2; i < n; i++)
if (a[i] != a[i-1] + initaldif)
return 0;
return 1;