C read access violation - Pointers - c

I'm new to C and I'm getting a little tangled up with the Visual Studio Code.
I did not understand what that meant.
When I run the code in another compiler it does run.
void swap(int* x, int *y);
int exe1(int* num1Ptr, int* num2Ptr, int* num3Ptr);
int main()
{
int a = 123, b = 456 , c =4;
int* pa, * pb ,*pc;
pa = &a;
pb = &b;
pc = &c;
printf("pa = %d , pb = %d, pc = %d\n", *pa, *pb, *pc);
exe1(pa, pb, pc);
printf("pa = %d , pb = %d, pc = %d\n", *pa, *pb, *pc);
return 0;
}
void swap(int* x, int* y) {
int temp = *x;
*x = *y;
*y = *x;
}
int exe1(int* num1Ptr, int* num2Ptr, int* num3Ptr) {
if (*num2Ptr > *num1Ptr) {
swap(*num1Ptr, *num2Ptr);
}
if (*num3Ptr > *num2Ptr) {
swap(*num3Ptr, *num2Ptr);
}
if (*num3Ptr > *num1Ptr) {
swap(*num3Ptr, *num1Ptr);
}
}

Your swap routine expects two pointers to int and you pass two ints to it. Remove superfluous asterisks from the calls:
swap(*num1Ptr, *num2Ptr);
should read
swap(num1Ptr, num2Ptr);
Plus the mistake inside swap() which Kaitou points out in the answer.

"read access violation" occurs when we try to access a memory address which we don't have access to. In this case it is because of swap(*num1Ptr, *num2Ptr);
This function expects a pointer (relating to memory address) and should be called as swap(num1Ptr, num2Ptr);
*num1Ptr dereferences the pointer, it is now an integer value, not a pointer to a valid address. For example *num1Ptr can be 123 in the above code. Whatever sits at memory address 123 is probably used by system and we don't have read/write access to it. Debugger throws access violation.
The compiler should also print warnings.
The swap function needs a fix *y = temp; as noted earlier.
Unrelated to your question, exe1 compares values in this order
p1 & p2
p2 & p3
p1 & p3
If this were intended as a sort function for example, the third condition can negate the first condition. You may want to change the order of comparison as shown below:
void swap(int* x, int* y)
{
int temp = *x;
*x = *y;
*y = temp;
}
void exe1(int* p1, int* p2, int* p3)
{
if (*p1 < *p2) swap(p1, p2);
if (*p1 < *p3) swap(p1, p3);
if (*p2 < *p3) swap(p2, p3);
}
int main()
{
int a, b, c;
a = 123, b = 456, c = 4;
exe1(&a, &b, &c); printf("%d, %d, %d\n", a, b, c);
a = 123, b = 456, c = 4000;
exe1(&a, &b, &c); printf("%d, %d, %d\n", a, b, c);
return 0;
}

void swap(int* x, int* y) {
int temp = *x;
*x = *y;
*y = *x; // this should be *y = temp;
}

Related

Why does this not swap a and b? [duplicate]

This question already has answers here:
Simple swap function...why doesn't this one swap?
(12 answers)
Closed 5 months ago.
I'm very new to C and just starting to learn pointers. I'm very confused by this piece of code in lecture. I'm wondering if anyone can explain it to help me understand.
#include <stdio.h>
void swap(int *p1, int *p2)
{ int *p;
p = p1; p1 = p2; p2 = p;
}
void main()
{ int a, b;
int *pointer_1, *pointer_2;
scanf("%d, %d", &a, &b);
pointer_1 = &a; pointer_2 = &b;
if (a < b) swap(pointer_1, pointer_2);
printf("\n%d > %d\n", *pointer_1, *pointer_2);
}
The problem is why this doesn't swap a and b?
In your code
p = p1; p1 = p2; p2 = p;
you're swapping the addresses (the change is local to the function scope). You need to swap the values (*p1, *p2) stored in those memory locations.
This function
void swap(int *p1, int *p2)
{ int *p;
p = p1; p1 = p2; p2 = p;
}
actually swaps nothing. The pointers are passed to the function by value
if (a < b) swap(pointer_1, pointer_2);
That is the function deals with its own local variables p1 and p2 that were initialized by copies of values of the original pointers used as argument expressions. Within the function these local variables are indeed swapped but the original pointers used as argument expressions stay unchanged.
You need to swap objects of the type int passed to the function swap by reference that is through pointers to them. That is you need to change values of the variables a and b defined in main.
So the function should look the following way
void swap(int *p1, int *p2)
{ int x;
x = *p1; *p1 = *p2; *p2 = x;
}
Dereferencing the pointers you get a direct access to the pointed variables a and b and can exchange their values.
If you want to exchange values of the pointers pointer_1 and pointer_2 themselves then the function can look the following way
void swap(int **p1, int **p2)
{ int *p;
p = *p1; *p1 = *p2; *p2 = p;
}
and the function will be called like
if (a < b) swap( &pointer_1, &pointer_2);
That is again the arguments must be passed by reference through pointers to them. In this case the values of the variables a and b will not be changed but values of the pointers will be changed.
Try yourself the both approaches and compare their results. Output in main the variables a and b and the values of the dereferenced pointers as for example
printf("a = %d, b = %d\n", a, b );
printf("*pointer_1 = %d, *pointer_2 = %d\n", *pointer_1, *pointer_2);
void swap(int *p1, int *p2)
{
int *p;
p = p1; p1 = p2; p2 = p;
}
Your function, swap, does not actually modify the values of p1 and p2
You can fix it by replacing p = p1; p1 = p2; p2 = p; with this
void swap(int *p1, int *p2)
{
int p;
p = *p1; *p1 = *p2; *p2 = p;
}
In this case, we modify the value of what the pointer is pointing to.

Are there Edge cases with swapping 2 values in memory using dereferenced pointers?

I wrote this simple function in C to swap the Value in 2 addresses in memory:
void pointersswap (int *ptr1, int *ptr2)
{
*ptr1 = *ptr1*(*ptr2);
*ptr2 = *ptr1/(*ptr2);
*ptr1 = *ptr1/(*ptr2);
}
I've been told there is an "edge case" that this program can encounter.
You can assume the input is correct (ptr1 and ptr2 actually hold address values and these addresses point to the memory where there's 2 ints which aren't 0). Math always checks out, even if either dereferenced pointer holds a negative number, or both are negative, or fractions.
For reference, this code Shouldn't have the same issue / edge case:
void pointersswap (int *ptr1, int *ptr2)
{
int temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}
What am I missing? are there really any limitations / edge cases in the first function?
Small clarification: assume there's not overflow / loss of information.
Firstly, "expressions" like *ptr1/*ptr2 won't work because /* is interpreted as the beginning of comments in C.
After replacing /* with / *, there are (at least) two cases in which the function won't work:
When the multiplication overflows.
When pointers to the same variable is passed to both a and b.
#include <stdio.h>
void pointersswap (int *ptr1, int *ptr2)
{
*ptr1 = *ptr1*(*ptr2);
*ptr2 = *ptr1/ *ptr2;
*ptr1 = *ptr1/ *ptr2;
}
int main(void) {
int a, b;
a = 999999; b = 888888;
printf("before: a = %d, b = %d\n", a, b);
pointersswap(&a, &b);
printf("after ; a = %d, b = %d\n", a, b);
a = 12345;
printf("before: a = %d\n", a);
pointersswap(&a, &a);
printf("after : a = %d\n", a);
return 0;
}
Output:
before: a = 999999, b = 888888
after ; a = 891245, b = -192
before: a = 12345
after : a = 1
I have been mislead, and so I mislead anyone who tried answering my question and for that I apologize. The two codes had the same edge case, which was that both pointers point to the same address, like MikeCAT suggested in his answer.

Pointers in C , understanding the difference

void noOfClients(struct noOfClients *q );
I understand that a pointer's name holds the memory address of a variable.
But, when * comes with a pointer, it represents the content of that location.
In the above line of code, when passing a by reference, we'd say:
void noOfClients( &q);
But why?
Thank you.
* has different meaning when it is used in a variable/argument declaration and when it is used as a pointer dereference operator.
In a variable/argument declaration, it declares the variable/argument to be of a pointer type.
struct noOfClients *q
declares q to be a pointer to a struct noOfClients.
When used in an expression,
*q
dereferences where q points to.
PS
void noOfClients( &q);
is not the right way to call the function. Just use:
noOfClients(&q);
That will work if q is declared as an object.
struct noOfClients q;
noOfClients(&q);
void func(foo *a);
This is a function prototype of a function taking a pointer to a foo. Some people like to write this as
void func(foo* a);
There's no difference, but you might say that the function takes a "foo-pointer", rather than a "pointer to a foo".
a is a foo*
*a is a foo
There is no difference.
because & indicates the address of a particular variable and when you deal with functions so when you pass a variable to the function so you do some changes in that variable, sometimes the reflection of value are not done in that variable but if you pass a variable with its address then reflection will be done properly just try and understand following two codes it will sure help you
without &
#include <stdio.h>
void swap(int, int);
int main()
{
int x, y;
printf("Enter the value of x and y\n");
scanf("%d%d",&x,&y);
printf("Before Swapping\nx = %d\ny = %d\n", x, y);
swap(&x, &y);
printf("After Swapping\nx = %d\ny = %d\n", x, y);
return 0;
}
void swap(int a, int b)
{
int temp;
temp = b;
b = a;
a = temp;
}
with &
#include <stdio.h>
void swap(int*, int*);
int main()
{
int x, y;
printf("Enter the value of x and y\n");
scanf("%d%d",&x,&y);
printf("Before Swapping\nx = %d\ny = %d\n", x, y);
swap(&x, &y);
printf("After Swapping\nx = %d\ny = %d\n", x, y);
return 0;
}
void swap(int *a, int *b)
{
int temp;
temp = *b;
*b = *a;
*a = temp;
}

Using pointers in C programming?

Right now I'm working on a program in C that takes 3 parameters; the address of a "first" integer, address of the "second" integer and the address in which to store the maximum of the two integers. So far I have the following basic code:
void max(int* x, int* y, int* z)
{
if (x > y) {
z = x;
}
else if (y > x){
z = y;
}
}
int main()
{
int x = 6;
int y = 4;
int z;
max(&x, &y, &z);
printf("max of %d and %d = %d\n", x, y, z);
x = 12;
y = 17;
max(&x, &y, &x);
printf("x = %d, y = %d\n", x, y);
}
When executed it outputs the following:
max of 6 and 4 = 32767
x = 12, y = 17
HOWEVER! I want it to output this instead:
max of 6 and 4 = 6
x = 17, y = 17
I'm not sure where I'm going wrong in my max function. Z should not be so huge and in the second print statement x should equal y. Any help is greatly appreciated, thanks!
As you probably already know, a pointer is a variable which contains the address in memory of another variable.
To access that memory we use The Unary operator & which gives us the address of a variable.
But accessing that memory is not all what a Pointer can do, we can with that pointer modify the value of that variable where the pointer points to.
For that we need to supply * to that pointer like this *ptr.
Let's take a look at the following program:
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
int main(void){
int a = 5;
int b = 10;
printf("A = %d\nB = %d\n\n\n",a,b);
int *pa = &a;
int *pb = &b;
*pa = 50;
*pb = 100;
printf("A = %d\nB = %d\n*PA = %d\n*PB = %d\n",a,b,*pa,*pb);
return 0;
}
The output will be:
A = 5
B = 10
A = 50
B = 100
*PA = 50
*PB = 100
As you can see A and B got new values. I hope you understand that.
when you pass things by pointer, if you want to get to the values, you need to do
(*x > *y)
Which gets the value pointed at by the pointer. (x and y are pointers, so they are going to contain memory addresses of the where the values are stored)
Needs to be:
if (*x > *y) {
*z = *x;
}
else if (*y > *x){
*z = *y;
}
You are comparing pointer addresses. You should de-reference the pointers for comparisons and assignments.
void max(int* x, int* y, int* z)
{
if (*x > *y) {
*z = *x;
}
else if (*y > *x){
*z = *y;
}
}

Why won't this C pointer code work?

Complete C newb here. Trying to learn/understand pointers by messing with simple code fragments.
#include <stdio.h>
void swap(int *px, int *py)
{
int tmp;
tmp = *px;
*px = *py;
*py = tmp;
}
main()
{
int *a, *b;
*a = 1;
*b = 2;
swap(&a,&b);
printf("%d %d\n", *a, *b);
}
Why is this not valid? The code works when I remove the dereferencing operator * from main.
Conceptually, this seems like it should work. I initialize a and b as pointers which point to int 1 and int 2, respectively. I then send their addresses to swap(), which should switch what they point to.
There are a couple of problems. First, the pointers a and b are not pointing to valid memory. So the assignment of the integer values is undefined (possible crash). Secondly, the call to swap (assuming a and b are pointing to valid memory) should not include the address (it is currently sending the address of the pointer variable).
The following changes would make it work:
int a, b;
a = 1;
b = 2;
swap(&a,&b);
printf("%d %d\n", a, b);
The swap() function is OK but inside main you are taking the addresses of pointers, so you're passing int** arguments to int* parameters.
int *a, *b;
swap(&a,&b);
To fix it, replace the code in main() with :
int a = 1, b = 2;
swap(&a,&b);
printf("%d %d\n", a, b);
Pointers point to data. A pointer itself doesn't comprise memory for storage, it just points to existing memory. So when you declare int *a; , you just have a garbage pointer with no useable value, and you mustn't dereference it.
The only sensible way to use pointers is to assign them the address-of something (or the result of some allocation function):
int i;
int *a = &i; // now a points to i
Therefore, the right way to use your swap function is to pass it addresses of integers:
int i = 10;
int j = -2;
swap(&i, &j);
a and b are uninitialized pointers, dereferencing them induces undefined behavior. You want:
int main() {
int a, b;
a = 1;
b = 2;
swap(&a,&b);
printf("%d %d\n", a, b);
return 0;
}
Your method signature is wrong. You ask for two pointers to int, yet you pass in two pointers to pointers to int.
When you say, " I then send their addresses to swap(), which should switch what they point to." Are you trying to change the address values within the pointer variables in main, to switch which bit of memory they are pointing to? In that case you will need another step of redirection:
#include <stdio.h>
void swap(int **px, int **py) {
int *tmp;
tmp = *px;
*px = *py;
*py = tmp;
}
int main (void) {
int x, y; /* storage to point to */
int *a, *b;
a = &x;
b = &y;
*a = 1;
*b = 2;
printf("(*a, *b, x, y) == (%d, %d, %d, %d)\n", *a, *b, x, y);
swap(&a, &b);
printf("(*a, *b, x, y) == (%d, %d, %d, %d)\n", *a, *b, x, y);
}
$ ./a.out
(*a, *b, x, y) == (1, 2, 1, 2)
(*a, *b, x, y) == (2, 1, 1, 2)
The x & y values have not changed, but a was pointing to x and now points to y and vice versa for b.

Resources