Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
At first code a[0] becomes 31 but in the second one a still 55. Can someone explain me the difference? What is the difference between changing a variable's and array's value in a function?
#include <stdio.h>
int h(int x[]);
int main()
{
printf("Hello, World!\n");
int a[0] = 55;
h(a);
printf("%d", a[0]);
return 0;
}
int h(int x[]) {
x[0] = 31;
}
#include <stdio.h>
int h(int x);
int main()
{
printf("Hello, World!\n");
int a= 55;
h(a);
printf("%d", a);
return 0;
}
int h(int x) {
x = 31;
}
And What about this code? This array is changed. I am really confused.
#include <stdio.h>
int h(int x[], int length);
int main()
{
int i;
int a[]= {5, 5, 5, 5};
h(a, 4);
printf("Array After Function Call\n");
for(i = 0; i < 4; i++) {
printf("%d ", a[i]);
}
return 0;
}
int h(int x[], int length) {
int i;
for(i = 0; i < length; i++) {
x[i] += x[i];
}
printf("Array in Function\n");
for(i = 0; i < length; i++) {
printf("%d ", x[i]);
}
printf("\n");
return 0;
}
And any decent book should have mentioned that arguments to functions are passed by value, meaning the value in the call is copied into the local function argument variable.
Modifying this local variable will only modify the local copy, not the value used in the call to the function.
One can overcome this problem by emulating pass by reference, which is done by passing a pointer to the variable:
void f(int *x)
{
*x = 123; // Dereference the pointer, to set the value of where it's pointing
}
int main(void)
{
int a = 0;
f(&a); // Pass a pointer to the variable a
}
This is really what's happening in the first program you show, you pass a pointer, and modify the value of where the pointer is pointing (the zero-sized array notwithstanding).
It seems that one of your major confusions is about your "array" argument.
When you declare a function as
void f(int a[]);
you don't actually declare an array argument: The compiler will treat it as a pointer and parse it as
void f(int *a);
Another point is that when you use array indexing, like
x[i] += x[i];
you are actually dereferencing the pointer, and write the values to the memory where the pointer is pointing. In fact, for any pointer or array x and index i, the expression x[i] is exactly equal to *(x + i).
Related
This question already has answers here:
What's the difference between passing by reference vs. passing by value?
(18 answers)
Closed 10 months ago.
In this array insertion code, the value of usedsize does not get updated when I increment it inside the void insert function. I want to know why that keeps happening and why the value of arr[i] gets updated when this doesn't?
#include <stdio.h>
#include <stdlib.h>
void insert(int arr[], int element, int index, int usedsize){
for(int i=usedsize;i>=index;i--){
arr[i+1]=arr[i];
}
arr[index]=element;
usedsize++;
}
void traverse(int arr[], int size){
for(int i=0;i<size;i++){
printf("%d",arr[i]);
printf("\t");
}
}
int main()
{
int narr[25]={5,7,12,34,45};
int index = 3;
int usize = 5;
int element = 21;
insert(narr,element,index,usize);
traverse(narr,usize);
return 0;
}
Like the commenters noted, the variable usedsize in the insert function is a copy.
why does the value of arr[i] get updated?
In C, the array name indicates the address of first element and arrays are always passed as pointers, even if you use the square bracket notation 0.
#include <stdio.h>
#include <stdlib.h>
void insert(int arr[], int element, int index, int *usedsize) {
printf("Address arr[%d] is %p\n", 0, &arr[0]);
printf("Address usedsize is %p\n", usedsize);
for(int i=*usedsize; i>=index; i--) {
arr[i+1]=arr[i];
}
arr[index]=element;
(*usedsize)++;
}
int main()
{
int narr[25]= {5,7,12,34,45};
int index = 3;
int usize = 5;
int element = 21;
printf("Address arr[%d] is %p\n", 0, &narr[0]);
printf("Address usize is %p\n", &usize);
insert(narr,element,index,&usize);
traverse(narr,usize);
return 0;
}
Original code:
- Address arr[0] is 0x7ffdf2f8b510
- Address usize is 0x7ffdf2f8b504
- Address arr[0] is 0x7ffdf2f8b510
- Address usedsize is 0x7ffdf2f8b4cc
Now:
- Address arr[0] is 0x7fff0c03d740
- Address usize is 0x7fff0c03d734
- Address arr[0] is 0x7fff0c03d740
- Address usedsize is 0x7fff0c03d734
This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 4 years ago.
I'm new to C, trying to get an user entered array into ascending order and print it. I'm trying to use selection sort for this.My devcpp crashes after accepting 1st input and when I tried to run it on an online c compiler, its giving segmentation error. Can someone tell me why is this happening here? TIA
#include<stdio.h>
void swap()
{
int *x, *y;
int temp = *x;
*x = *y;
*y = temp;
}
void ss(int A[], int n)
{
int i, j, min;
for(i=0; i<n-1;i++)
{
min = i;
for(j=i+1; j<n; j++)
{
if (A[j]< A[min])
{
min = j;
}
swap(&A[min], &A[i]);
}
}
}
void print(int A[], int n)
{
int i;
for(i=0; i<n; i++)
{
printf("%d",A[i]);
}
}
int main()
{
int A[4], i, n;
printf("Enter the elements");
scanf("%d", &A[i]);
n=4;
ss(A,n);
printf("Sorted array \n");
print(A,n);
return 0;
}
I want the user entered array in ascending order.
Your swap() function has no parameters, and the pointers x and y are not pointing to anything. Your segmentation fault is coming from statements like:
int temp = *x;
Because *x has no determined value, you didn't assign an address to x of any existing value in your program, yet your trying to indirect it here.
Instead, put parameters in your swap function:
void swap(int* x, int* y)
{
int temp = *x;
*x = *y;
*y = temp;
}
And then in the outer scope, pass proper, existing values on the stack's addresses to this swap function.
Well, this is wrong, for a start:
void swap()
{
int *x, *y;
int temp = *x;
*x = *y;
*y = temp;
}
This creates two brand new pointers within the function, with arbitrary values, and then attempts to dereference them, something that's undefined behaviour.
Since you're passing two pointers to the swap function with swap(&A[min], &A[i]), you should receive those in the parameter list so that you can operate on them:
void swap(int *x, int *y) {
int temp = *x;
*x = *y;
*y = temp;
}
And, though it's not a bug, you may want to consider using more descriptive names than A or ss (e.g., dataArray and SelectionSort).
This will tend to make your code much more readable and therefore maintainable if you have to, for example, come back and modify it twelve months in the future.
You will also need a loop in your main function to get the four values. At the moment, you get only one and with an arbitrary index i which may cause you undefined behaviour again.
Since you've already done similar loops in the other two functions, I'll assume you can handle this task without me giving you the code.
There are quite a few errors buddy. I'm listing them out below:
In the main(), check how you are accepting the array values from the user. i is undefined and you are trying to insert into just A[i] without using a for loop or without defining i either. That's where you get your seg fault.
for(i = 0; i < 4; i++)
scanf("%d", &A[i]);
Another mistake is in the way you have defined the swap() function . Since you have called swap function as swap(&A[min], &A[j]);, i.e., passing addresses as parameters, your function too needs to have pointers to these addresses.
should be something like this: void swap(int* x, int* y).
As a result of the change we made in the 2nd point above, you need to remove this line ==> int *x, *y;, which declares the 2 pointers again inside the swap function.
here is the code which should work:
#include<stdio.h>
void swap(int* x, int* y)
{
int temp = *x;
*x = *y;
*y = temp;
}
void ss(int A[], int n)
{
int i, j, min;
for(i=0; i<n-1;i++)
{
min = i;
for(j=i+1; j<n; j++)
{
if (A[j]< A[min])
{
min = j;
}
swap(&A[min], &A[j]);
}
}
}
void print(int A[], int n)
{
int i;
for(i=0; i<n; i++)
{
printf("%d\t",A[i]);
}
}
int main()
{
int A[4], i, n;
printf("Enter the elements:\n");
for(i = 0; i < 4; i++)
scanf("%d", &A[i]);
n=4;
ss(A,n);
printf("Sorted array \n");
print(A,n);
return 0;
}
Which would give the output as follows:
Enter the elements:
1 2 3 4
Sorted array
4 3 2 1
Sorry for that title. I really didn't know how to define this problem.
I was needed to declare integer array of N numbers and to fill it with random nums in void function. Then that array needs to be printed in main. The thing is that i am not allowed to use printf in void function so only way to print in main is to use pointers I guess. My knowledge is limited as I am beginner at pointers. Thx in advance and sorry for bad english.
Here is my code so far. When I compile it marks segmentation error.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form();
int main()
{
int N, a[100];
printf("Input index: \n");
scanf("%d", &N);
form(N, &a);
printf("Array: \n");
for (int i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr[100])
{
srand(time(NULL));
for (int i = 0; i < N; i++) {
*ptr[i] = rand() % 46;
}
There are several issues in your code.
1) Your array decalaration form() is obsolete. Use proper prototype.
2) For declaring a VLA, declare it after reading N instead of using a fixed size array.
3) An array gets converted into a pointer to its first element when passed to a function. See: What is array decaying?
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form(int, int*); /* see (1) */
int main(void) /* Standard complaint prototype for main.
If you need to pass arguments you can use argc, and argv */
{
int N;
printf("Input size: \n");
scanf("%d", &N);
int a[N]; /* see (2) */
form(N, a); /* see (3) */
printf("Array: \n");
for (int i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr) { /* Modified to match the prototype
srand(time(NULL));
for (int i = 0; i < N; i++) {
ptr[i] = rand() % 46;
}
}
So a couple things:
void form();
As Olaf was alluding to, this declaration is incorrect - you are missing the applicable parameters. Instead, it should be
void form(int N, int ptr[100]);
The main reason your program is crashing is because of the following line:
*ptr[i] = rand() % 46;
You are dereferencing the pointer at i, which is actaully giving you a number - what you want is to assign the value of the pointer at i the new random value:
ptr[i] = rand() % 46;
As related reading, see this question about passing an array in as a function parameter (basically, int ptr[] is the same thing as int * ptr)
Small modifications on your code:
1) Correction and simplification of parameter handling at function call. Just hand over "a", it's an array, so it is an address, you can use int *ptr, or int ptr[], or int ptr[100] in the formal parameter list for it. So you can use simply ptr[i] in your function.
2) Make a prototype for function from old-style declaration providing parameter list.
3) int i; declaration before the for loop - not mandatory, depends on your compiler standard
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form(int N, int *ptr);
int main()
{
int N, a[100];
printf("Input index: \n");
scanf("%d", &N);
form(N, a);
printf("Array: \n");
int i;
for (i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr)
{
srand(time(NULL));
int i;
for (i = 0; i < N; i++) {
ptr[i] = rand() % 46;
}
}
I have the following code
void fun(int * d)
{
d+=1;
}
int main()
{
int * f=malloc(5);
f[0]=0;f[1]=1;f[2]=2;f[3]=3;f[4]=4;
fun(f);
printf("value : %d\n",*f);
return 0;
}
So, i pass an integer pointer to function and increment it there. I want that increment to persist when it returns to main.
When I print the value, The output is '0'. But I want the output to be '1' as I have incremented the value in function.
So, briefly, my question is, how to persist the changes made to a pointer?
Assuming you want to increment the pointer, not the value, you have two options:
recast the function to void fun(int ** d), use (*d)+=1; in the function body, and call using fun(&f);
recast the function to int* fun(int* d), and return the new value.
If you want to increase the value, then use (*d)+=1; in the function body.
You don't need the parentheses around *d: I've put them in for clarity.
You forgot * in d+=1;
When you pass that pointer you have access to f[0] with that approach:
Take a look here:
#include <stdio.h>
#include<stdlib.h>
void fun(int *d){
*d+=1;
}
int main(void){
int i;
int *f=malloc(5 * sizeof int);
f[0]=0;f[1]=1;f[2]=2;f[3]=3;f[4]=4;
for(i=0;i<5;i++){
printf("%d ",f[i]);
}
printf("\n");
fun(f);
for(i=0;i<5;i++){
printf("%d ",f[i]);
}
free(f);
return 0;
}
Output:
0 1 2 3 4
1 1 2 3 4
Or if you try to add +1 to all elements you can do something like this:
#include <stdio.h>
#include<stdlib.h>
int *fun(int *d, int len){
int i;
int *newArray = d;
int newValue = 1;
printf("\n");
for(i = 0; i < len; i++) {
newArray[i] += newValue;
}
return newArray;
}
int main(void){
int i;
int f[] = {0,1,2,3,4};
int *newArray;
f[0]=0;f[1]=1;f[2]=2;f[3]=3;f[4]=4;
for(i=0;i<5;i++){
printf("%d ",f[i]);
}
printf("\n");
newArray = fun(f,5);
for(i=0;i<5;i++){
printf("%d ",newArray[i]);
}
return 0;
}
Output:
0 1 2 3 4
1 2 3 4 5
And by the way you forgot to free f.
You have to pass the address of the pointer, so:
void fun(int **val) {
*val++;
....
}
int main() {
...
fun(&f);
...
}
I keep getting a segmentation fault in this code:
#include <stdio.h>
void FillArray(int *array, int);
#define MAX 256
int main()
{
int *array[MAX], size = 100;
FillArray(*array, size);
return 0;
}
void FillArray(int *array, int size)
{
int i, temp;
for (i = 0; i < size; i ++)
{
temp = (rand()%101);
*array = temp;
printf ("array[%d]. %d\n", i, *array);
array += i;
}
printf ("AJGIUEROGUSHFDJGJDFK/n");
}
I put the printf on the last line so that i could tell if it would reach that point, so far it hasn't.
Edit: I added code. I have to use pointer arithmetic instead of array indexes.
Your array in main is declared as an array of int * pointers. This array is not initialized, i.e. all elements contain garbage values.
Layer your FillArray call in main
FillArray(*array, size);
passes the value of *array to FillArray function. *array is the same as array[0] - it is an uninitialized garbage pointer that points nowhere.
Inside FillArray function you are attempting to access (and write) data through that uninitialized garbage pointer. Expectedly, the code crashes.
As is always the case with invalid code, there's no way to fix the error until you explain what you are trying to do.
I can only guess that all you needed is an array of int elements, not int * elements. I.e. your array in main was supposed to be declared as int array[MAX]. And FillArray should have been called as FillArray(array, size). Also, inside the cycle it is supposed to be array += 1 (or just ++array), not your array += i, which does not make any sense.
If wanna fill the array passed to your function, then change
array = &temp;
to
*array = temp;
And also change
array += i;
to
array++;
EDIT: OP edited his question and want to fill an array of integers. You need to chage the declaration of your array
int *array[MAX], size = 100; // Declare an array of pointers
to
int array[MAX], size = 100; // Declates an array of ints
Your loop should just be:
int i, temp;
for (i = 0; i < size; i ++)
{
temp = rand() % 101;
array[i] = temp;
printf ("array[%d] = %d\n", i, array[i]);
}
This will do what you want. There's no need to re-assign array inside the function, although you can. It's easier to just use the indexing operator []. Remember that
a[i]
is the same as
*(a + i)
regardless of the types involved (but generally a is a pointer type and i an unsigned integer) as long as the sum is a pointer of course.
There are errors in main(), too:
The array should just be int array[MAX];.
The call should just be FillArray(array, size);.
probably your want.
#include <stdio.h>
#include <stdlib.h>
void FillArray(int *array, int);
#define MAX 256
int main(){
int array[MAX], size = 100;
FillArray(array, size);
return 0;
}
void FillArray(int *array, int size){
int i;
for (i = 0; i < size; i++){
*array = rand()%101;
printf ("array[%d]. %d\n", i, *array);
++array;
}
}
int *array[MAX] is an array of MAX pointers to int, from which you pass the 1st to the function. There are no ints defined where the latter points to.
To fix this appliy the changes void FillArray(int *array, int size) provided by the other answers and then call it like this:
int main(void)
{
int array[MAX], size = 100;
FillArray(array, size);
return 0;
}
Code is fine except for your perception that *array = &array, which is wrong !!
Below points might help in understating pointers better:
*array = array[0]
array = &array[0]
*(array+i) = array[i]
Made changes to your code and it should work fine:
#include <stdio.h>
void FillArray(int *array, int);
#define MAX 256
int main()
{
int *array, size = 100;
array=(int *)calloc(MAX,sizeof(int));
if(array !=NULL)
{
FillArray(array, size); /* While calling send &array[0] but not array[0] */
}
return 0;
}
void FillArray(int *array, int size)
{
int i, temp;
for (i = 0; i < size; i ++)
{
temp = (rand()%101);
*(array+i) = temp;
printf ("array[%d]. %d\n", i, *(array+i));
/* array += i; <-- not necessary */
}
printf ("AJGIUEROGUSHFDJGJDFK/n");
}