Why won't changing this value work? - c

So I'm trying to change the value at x[2] from 0 to 8 using a method, the way I have this isn't working. How can I do this? I tried searching around but came to no avail.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void changevar(int* x){
int* y;
y = &x[2];
y = 8;
}
int main(int argc, char** argv){
int* c;
c = (int*) malloc(sizeof(int));
printf("here %d\n", c[2]);
changevar(&c);
printf("here %d\n", c[2]);
free(c);
}
EDIT: I'm new to pointers

You first need to allocate enough space:
c = malloc(3 * sizeof(int));
Notice that I didn't cast the return value.
The values are not initialized to zero. They can be anything ("undefined"). You can clear it with:
memset(c, 0, 3 * sizeof(int));
Next, you'll need to pass this value as is to your function. (It's already a pointer, after all.)
changevar(c);
Within your function, you'll need to dereference the address to access it:
*y = 8;
Those are the errors I see.

So there are two issues that are standing out to me.
You're only allocating memory for one int in your malloc call but trying to access memory that would suggest you allocated a minimum space for 3 ints.
Your function's parameter is supposed to be a int*, however with changevar(&c) you're passing in a int** because you giving the address of a pointer.
To fix these only a couple of changes need to be made...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void changevar(int* x){
x[2] = 8; // <-- can be simplified to this one line
}
int main(int argc, char** argv){
int* c;
int amt = 3; // <-- number of ints you want to be able to have space for
c = malloc(sizeof(int) * amt); // <-- multiply the size and the amount you want
printf("here %d\n", c[2]);
changevar(c); // <-- remove the '&' from the argument to just pass the pointer 'c'
printf("here %d\n", c[2]);
free(c);
}
The output becomes:
here 0
here 8

Garbage values are being printed because size of array c is 1.
c = (int*) malloc(sizeof(int));
will create an array c of size 1.
c[2] is a garbage value. (In most systems, 0 is printed instead of a garbage number.)
Your &c[2] and y do not refer to the same address.
What you want to do is probably this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void changevar(int** x){
*(*x+2)=8;
}
int main(int argc, char** argv){
int* c;
c = (int*) malloc(3*sizeof(int));
for(int i=0;i<3;i++){
c[i]=0;
}
printf("here %d\n", c[2]);
changevar(&c);
printf("\nhere %d\n", c[2]);
free(c);
}
Prints:
here 0
here 8

Related

Array pointer to find largest number

#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a= malloc(sizeof(int)*10);
scanf("%d %d",a,a+1);
if(*a<*(a+1))
{
*a=*(a+1);
}
printf("%d",*a);
return 0;
}
Can I use the same array pointer to input 2 numbers and find largest number among them, as shown in the above code?
Yes, it will work, although it might be perceived as more readable to use bracket notation for array elements. You also only need to malloc space for 2 elements.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a = malloc(sizeof(int) * 2);
scanf("%d %d", &a[0], &a[1]);
if(a[0] < a[1])
{
a[0] = a[1];
}
printf("%d", a[0]);
return 0;
}
Read more about pointers and how they work
Yes, you can. Because when you say *a you are pointing to the 0th location of the array and getting the value there and when you say *(a+1) you are pointing to 1st location of the array. Same analogy for &a and &(a+1).

If I allocate only 4 bytes for single int, how then pointer can store second int?

As I found on one site following code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *p1 = malloc(4*sizeof(int)); // allocates enough for an array of 4 int
int *p2 = malloc(sizeof(int[4])); // same, naming the type directly
int *p3 = malloc(4*sizeof *p3); // same, without repeating the type name
if(p1) {
for(int n=0; n<4; ++n) // populate the array
p1[n] = n*n;
for(int n=0; n<4; ++n) // print it back out
printf("p1[%d] == %d\n", n, p1[n]);
}
free(p1);
free(p2);
free(p3);
}
Output:
p1[0] == 0
p1[1] == 1
p1[2] == 4
p1[3] == 9
Now following that code above I did this:
#include <stdio.h>
#include <stdlib.h>
#include "Header.h"
int main()
{
int *ip = (int*)malloc(1 * sizeof(int));
ip[0] = 2;
ip[1] = 9;
printf("%d %d",ip[0],ip[1]);
return 0;
}
Output: 2 9
So how then my pointer *ip can store more than one int when I only allocated bytes for single int?
You're writing into memory which is outside of the bounds of the array. Sadly, there is no compiler check for this, but it sometimes works.
Note: This is undefined behavior and should not be used under any circumstances.
Remember, ip[1] is equivalent to *(ip + 1), which is syntactically valid for any pointer, even if ip is pointing to single int and not an array of ints.
Dereferencing or writing to ip[1] is undefined behavior. Try adding free(ip) before the return 0 in your second program and observe the behavior then.

C - swapping two 2D arrays by switching pointers

I would like to swap two variables containing 2D arrays. I believe this can be simply done by swapping their pointers. I tried this code, but it does not work and I have no idea why, perhaps I am not understanding pointers correctly.
#include <stdio.h>
void swap(int ***a, int ***b) {
int ** temp = *a;
*a = *b;
*b = temp;
}
int main(void) {
int a[10][10];
int b[10][10];
a[1][5] = 4;
b[1][5] = 2;
printf("%d, %d\n", a[1][5], b[1][5]);
swap(&b, &a);
printf("%d, %d\n", a[1][5], b[1][5]);
return 0;
}
This outputs
4, 2
4, 2
I would expect it to output
4, 2
2, 4
So, what am I doing wrong?
a and b in main function are not pointers but arrays.
If you want to use pointers, use pointers.
#include <stdio.h>
#define N 10
void swap(int (**a)[N][N], int (**b)[N][N]) {
int (*temp)[N][N] = *a;
*a = *b;
*b = temp;
}
int main(void) {
int a[N][N];
int b[N][N];
int (*pa)[N][N] = &a;
int (*pb)[N][N] = &b;
(*pa)[1][5] = 4;
(*pb)[1][5] = 2;
printf("%d, %d\n", (*pa)[1][5], (*pb)[1][5]);
swap(&pb, &pa);
printf("%d, %d\n", (*pa)[1][5], (*pb)[1][5]);
return 0;
}
This would not work because what you are swapping is actually what the variables in the swap() function are pointing to, and not what they are pointing at. Its like if a was pointing at 5 and b was pointing at 6 in the swap() function, then it will make a point at 6 and b point at 5, without changing the contents of the memory. This would mean the in the main() function they would be residing at the same place and would be getting pointed by the same variable a and b (different from the variable in swap())
To swap you need to swap the contents of that memory in the swap() function, so that it is reflected in the main() function.
Recall that while doing swapping using pointers, one sends the address and actually swaps the content by dereferencing (*p and *q).

C: segmentation fault when running function from another file

When ever i run this code, it works up until i get to the printf statement in my main function, thats when i get a segmentation fault error. so it will run like "enter how many numbers you want" 3 "Enter the numbers in the array" 1 2 3 array[0] = 1 array[1] = 2 array[2] = 3 segmentation error. Can you guys please tell me why im getting this error and how to fix it? thank you
//pathfinder.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Vector.h"
int main()
{
Vector *V;
VectorRead(V);
printf("%d", V->item[0]);
return 0;
}
//Vector.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
typedef struct{
int *item;
int size;
} Vector;
void VectorRead(Vector *V) ;
void VectorRead(Vector *V)
{
int N;
printf("Enter how many numbers you want?\n");
scanf("%d", &N);
V = (Vector *)malloc(sizeof(Vector *) * N);
V->size = N;
V->item = (int *)malloc(sizeof(int *) * V->size);
printf("Enter the numbers that you want in your array\n");
int i = 0;
while(i < V->size && scanf("%d", &(V->item[i++])) == 1);
int j;
for(j = 0; j< V->size; j++){
printf("array[%d]=%d\n", j, V->item[j]);
}
}
This error has nothing to do with your code being in different files.
When you call VectorRead(), you are passing a pointer value. Inside that function, you are setting the local V to the return value of a call to malloc(). There is no way for that local V to return back to the caller.
You will need to do something to return the newly allocated value of V back to the caller. Changing your function to return a Vector * (instead of taking one as a parameter) would be a good approach.
Your local Vector, V, is not being modified when VectorRead() is called. Try instead accepting a Vector ** in your function:
void VectorRead(Vector **V)
and modify the function accordingly.
Or, since your function has no return value, and as #EOF points out in the comments, it is probably a better idea to not take a parameter, and simply return the Vector *:
Vector *VectorRead(void)

How to realloc based on size of array?

Say you malloc enough memory space to hold an array of size 20. The program is running and now I need enough memory for an array of size say 40. I tried to do this using realloc but it doesn't seem to be working. My code is the following(I'm trying to find the sum of all even-valued fibonacci terms below 4million):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv){
int i,sum,size;
int *fibo;
size = 20; //initial size of array
fibo = (int *) malloc(size*sizeof(int));
fibo[0]=1;
fibo[1]=1;
i=2;
sum=0;
while(fibo[i-1]<4000000){
fibo[i] = fibo[i-1]+fibo[i-2];
printf("fibo[%d] = %d\n", i, fibo[i]);
if(fibo[i]%2 == 0){
sum+= fibo[i];
}
i++;
if(i>size){
fibo = (int *) realloc(fibo, (size *= 2)*sizeof(int));
}
}
printf("Sum = %d\n", sum);
return 0;
}
Anyone know why realloc is failing, and how I can fix it?
During the last iteration, i equals 20 but the expression
if(i>size)
is false, so you do not actually use realloc, then by writing to
fibo[20]
the program is accessing part of the memory that does not belong to it. Changing the expression to
if(i>=size)
should fix it :)

Resources