New to C here, I am creating an insert function that will insert any value to an array provided I give the position of the array.
For example, here is what I have tried:
#include <stdio.h>
#include <stdlib.h>
int insert(int A[], int N, int P, int KEY){
int i = N - 1;
while(i >= P){
A[i+1] = A[i];
i += 1;
}
A[P] = KEY;
N = N+1;
return *A;
}
int main(void){
int arr[5] = { 1, 2, 3, 4, 5 };
size_t n = sizeof(arr)/sizeof(arr[0]);
int p = 3;
int K = 2;
int result;
result = insert(arr, n, p, K);
printf("Insert values: %d", result);
return 0;
}
However, I get the following error:
zsh: segmentation fault ./insert
Accessing out of bounds memory:
The statement is the while loop.
A[i + 1] = A[i];
is incorrect. Arrays indices start at 0 in C. Your array consists of 5 elements. The 5th int is the element [4]. You declared i to be (N - 1), which is correct, but then A[i + 1] becomes A[5] which is out of bounds, and results in undefined behaviour.
The memory not allocated should not be read.
As an aside, you can use:
i++;
N++;
as shorthand for:
i = i + 1;
N = N + 1;
Maybe you are not aware of what is segmentation fault and when does it occur. Lets start with the segmentation fault.
Segmentation fault:
A segmentation fault occurs when your program attempts to access an area of memory that it is not allowed to access. In other words, when your program tries to access memory that is beyond the limits that the operating system allocated for your program.
Segmentation faults are mostly caused by pointers that are −
Used to being properly initialized.
Used after the memory they point to has been reallocated or freed.
Used in an indexed array where the index is outside of the array bounds.
Now back to your problem, here you have used i = N - 1 which is 4. Then in the while loop, you are trying to access A[i+1] or A[5] which is outside of the array bounds. Thus you are getting segmentation faults.
Related
I am trying to calculate result of the floor function for floats <= 9999.
#include <stdlib.h>
include <stdio.h>
#include "string.h"
int main(int argc, char* argv[]) {
int i, j, k;
int x[1000];
for(i = 0; i < 10000; ++i){
x[i] = i;
}
printf("Enter a float in 0..9999: ");
scanf("%d", k);
tester(x, k);
}
int tester(int* c, int k) {
printf("x[%d] = %d\n", k, c[k]);
}
When compiler came to;
for(i = 0; i < 10000; ++i){
x[i] = i;
}
it gives segmentation fault;
x[i] = i;
here.
I have already checked similar questions about assigning segmentation fault but I couldn't find any solution way. Can anyone help?
The array x is of length 1,000, but you're treating it in the loop as if it's of length 10,000. Accessing x[i] for i greater than or equal to 1,000 is undefined behaviour because the index is out of the array's range.
Thus, a segmentation fault is occurring because your program is accessing memory that it is not allowed to access.
The variable k is initialised and when getting input "&" is missing in the scanf statement. This might have come under segmentation fault since the value "k" is passed in the function tester(). Generally in C lang, we get input with "&", unless if it is a string you don't necessarily mention that in the scanf statement!!.
What I need very precisely is an array A[10] and each of its element pointing to the respective element of array B[10] whose each element store its index.
Hence, A[1] points to B[1] and B[1] has value of 1.
So, when I call *A[1] or *B[1], I get 1.
I know it can be super easy if the array B[10] is not an array of pointers but of integers but I need this for another purpose.
This is what I did but segmentation fault was offered.
#include <stdio.h>
int main() {
int *A[10];
int *B[10];
for(int i=0; i<10; i++) {
A[i] = B[i];
*B[i] = i;
printf("\n%d %d",*A[i],*B[i]);
}
}
By the way, I am not very proficient in pointers.
Your commented code :
int main() {
int *A[10]; // an array of 10 pointers, each of them pointing nowhere
int *B[10]; // an array of 10 pointers, each of them pointing nowhere
// now each array a and b contain 10 uninitialized pointers,
// they contain ideterminate values and they point nowhere
for(int i=0; i<10; i++) {
A[i] = B[i]; // copy an uninitialized pointer
// this usually works but it's pointless
*B[i] = i; // you assign i to the int pointed by *B[i]
// but as *B[i] points nowhere you end up with a segfault
printf("\n%d %d",*A[i],*B[i]); // you never get here because the previous
// line terminates the program with a segfault,
// but you'd get a segfault here too for
// the same reason
}
}
Your program is basically equivalent to this:
int main() {
int *a; // a is not initialized, it points nowhere
*a = 1; // probably you'll get a segfault here
}
Accessing the thing pointed by a pointer is called dereferencing the pointer. Dereferencing an uninitialized pointer results in undefined behaviour (google that term), most likely you'll get a seg fault.
I'm not sure what you're trying to achieve, but you probably want something like this:
#include <stdio.h>
int main() {
int* A[10];
int B[10];
for (int i = 0; i < 10; i++) {
A[i] = &B[i];
B[i] = i;
printf("%d %d\n", *A[i], B[i]);
}
}
I am trying to allocate a big block of memory.
I ran this code firt,
#include <stdio.h>
#include <stdlib.h>
int main()
{
long i;
long n = 50000;
printf("trying to malloc %ld memory. ", n);
long *ptr;
ptr = (long*) malloc(n * sizeof(int));
if(ptr == NULL)
{
printf("Error! memory not allocated.");
exit(0);
}
for(i = 0; i < n; ++i)
{
*(ptr+2*i) = 9;
}
for(i = 0; i < 5; ++i)
{
printf("%ld ", *(ptr+2*i));
}
return 0;
}
and then I got this error
Segmentation fault (core dumped)
I know this "you are accessing memory that does not belong to you.", but why
PS:
long n = 5000; works well
When you have a pointer to a datatype, adding 1 to that pointer will actually offset the address by however large the datatype is. If I have a pointer to an integer array at 0x0000, doing myArray += 1; will result in my pointer having the value of 0x0004 (assuming an integer is 4 bytes on my system)
Knowing this, you can see how the line *(ptr+2*i) will go out of the bounds of your array for all values of i greater than i/2
Normally, since you are dynamically creating this array, writing to these addresses would just corrupt heap memory and not cause a segfault. The problem is that your program is going so far out of bounds, it is past the heap and going into memory that doesn't belong to your program. This is why it segfaults for 50000 and not 5000.
This question already has an answer here:
Definitive List of Common Reasons for Segmentation Faults
(1 answer)
Closed 5 years ago.
My program need to have a function in which it finds the largest element of an array. It then returns the position of largest element. However, when finding the largest element, I am only allowed to use pointer arithmetic.
#include <stdio.h>
int *largest(int *array, int size){
int *p1 = array;
int *count, max = *p1;
for(*count = 0; count < p1 + size - 1; p1++){
if (max < *p1){
max = *p1;
count++;
}
}
return count;
}
int main(void){
int *array, size = 10;
printf("enter elements; ");
for(int i = 0; i < size; i++){
scanf("%d ", &array);
array++;
}
printf("\nThe largest element in the array is in element %d", *largest(array, size));
}
However, when I run the program, after enter values for the elements, it gives me:
segmentation fault (core dumped)
Mistakes in the function main:
You didn't allocate memory for the array. You need to add line array = (int*) malloc(sizeof(int) * size);. Without this line you get segmentation fault.
Another mistake is in filling array. Array is pointer already so you don't have to reference it again. Now you are changing pointer, not array values
Potential bug: In loop when you fill array, you increase pointer, so you loose information about beginning of array. You can get it again after loop doing array = array - size;, but it won't work if you break loop earlier. It is better to work with temporary pointer.
Mistakes in the function largest:
You created pointer count, which is not allocated and then in for loop initialization you write value 0 to unknown address. Causes segmentation fault.
In for loop you are trying to read memory from address 0 to address array + size - 2, but you want to read it from beginning of array to the end of array which is from array to array + size - 1.
Returning count makes no sense, but to sum it up, look at the example.
Pointer is just number which is address to memory, so when you don't allocate it or don't assign existing pointer, then it points randomly to memory and OS don't let you access that memory. It can happen that you will read something from random pointer, but new compilers sets initial value to 0. In BSD you can read from address 0, but linux cause segmentation fault (I hope that I didn't switch it). Writing to address 0 causes segmentation fault in both systems.
You should also check in function if you got valid pointer and allocation can fail so you need to check pointer immediatelly after allocation too. To sum this: Never trust pointer, always check it's validity.
Example doesn't check validity of pointers.
#include <stdio.h>
int *largest(int *array, int size){
int *end = array + size; // address behind array
int *max = *array; // address with largest value
for(; array < end; ++array){ // you dont need initialization since the array points to beginning
if (*max < *array){ // compare values, not address
max = array; // save position of pointer with largest value
}
}
return max; // return address with largest value
}
int main(void){
int *array, size = 10;
array = (int*)malloc(sizeof(int) * size); // allocate memory
printf("enter elements; ");
int *tmp = array; // temporary variable to not loose information about beginning of array
for(int i = 0; i < size; i++){
scanf("%d ", tmp); // reference is not needed since tmp is already pointer to value
tmp++;
}
printf("\nThe largest element in the array is in element %d", *largest(array, size));
}
I have a random number generator feeding numbers into an array, but when I print out the table, the last line is always a set of values out of the boundaries that I defined in the following function:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int temp[22];
int n;
for(n=0; n<23; n++){
temp[n] = rand()%(100 + 1 - 60) + 60;
printf("%d , %d \n", n, temp[n]);
}
return 0;
Ive created something of this nature before, but now its acting up, I just dont know where.
You are accessing the array outside the bounds which is undefined behaviour.
Instead make use of sizeof operator to avoid such problems:
for(n = 0; n < sizeof temp/sizeof temp[0]; n++)
But note that if temp were to be an malloc'ed pointer (int *temp = malloc(23 * sizeof *temp);) then sizeof wouldn't work.
Your array is being accessed outside of its bounds.
int temp[22];
This declaration assigns 22 indices to temp, temp[0] is the first
value and temp[21] is the last value you can access in your array. Counting 0, from 0..21 = we have 22 values
Your for loop is incorrect:
for(n=0; n<23; n++)
This will make the program attempt to access temp[22], which doesn't exist. You need to change it to:
for(n=0; n<22; n++)
Furthermore:
return 0; needs to be inside and at the end of your main() function. It's possibly a typo, but you're missing a closing brace } in your main() function, at least how you posted it.