[] precedence over * operator - c

Somewhere in my code I am doing something very bad. I'm getting undefined behavior in my extrema variable when it does run but most of the time it doesn't even run. Any help would be really great.
#include <stdio.h>
void get_extrema(int quadrant, int **extrema)
{
if (quadrant == 1)
{
*(extrema)[0] = 0;
*(extrema)[1] = 90;
}
else if (quadrant == 2)
{
*(extrema)[0] = -90;
*(extrema)[1] = 0;
}
}
void print(int* arr)
{
printf("%i",arr[0]);
printf(",");
printf("%i\n",arr[1]);
}
int main(void)
{
int *extrema = (int*)malloc(2*sizeof(int));
get_extrema(1,&extrema);
print(extrema);
get_extrema(2,&extrema);
print(extrema);
}
I also tried editing the extrema array using pointer arithmetic like the following:
**(extrema) = 0;
**(extrema+1) = 90;
But that did not work either. I really have no clue where this is going wrong and I could really use some help.

The reason you get undefined behavior is that the subscript operator [] takes precedence over the indirection operator *. The value of extrema is indexed as an array of pointers, which is incorrect, because there's only a single pointer there.
Since you are passing a pointer to a pointer, you need to put the asterisk inside parentheses:
if (quadrant == 1)
{
(*extrema)[0] = 0;
(*extrema)[1] = 90;
}
else if (quadrant == 2)
{
(*extrema)[0] = -90;
(*extrema)[1] = 0;
}
Demo on ideone.

a[b] is equal to *(a + b), but has higher precedence than the *. (And like a + b is b + a, so is a[b] equal to b[a]; and 5[a] equal to a[5]).
Thus:
*(extrema)[1] = 90;
// is equal to
*(*(extrema + 1)) = 99;
// When what you want to do is
*((*extrema) + 1) = 99;
// which is of course equal to
(*extrema)[1] = 99;
However, an even better question is: why are you using the double pointer, when it is not needed.
void get_extrema(int quadrant, int *extrema)
{
if (quadrant == 1)
{
extrema[0] = 0;
extrema[1] = 90;
}
else if (quadrant == 2)
{
extrema[0] = -90;
extrema[1] = 0;
}
}
void print(int *arr)
{
printf("%i,%i\n", arr[0], arr[1]);
}
int main(void)
{
int *extrema = (int *)malloc(2 * sizeof (int));
get_extrema(1, extrema);
print(extrema);
get_extrema(2, extrema);
print(extrema);
}

Related

Segmentation fault during memory allocation [duplicate]

Somewhere in my code I am doing something very bad. I'm getting undefined behavior in my extrema variable when it does run but most of the time it doesn't even run. Any help would be really great.
#include <stdio.h>
void get_extrema(int quadrant, int **extrema)
{
if (quadrant == 1)
{
*(extrema)[0] = 0;
*(extrema)[1] = 90;
}
else if (quadrant == 2)
{
*(extrema)[0] = -90;
*(extrema)[1] = 0;
}
}
void print(int* arr)
{
printf("%i",arr[0]);
printf(",");
printf("%i\n",arr[1]);
}
int main(void)
{
int *extrema = (int*)malloc(2*sizeof(int));
get_extrema(1,&extrema);
print(extrema);
get_extrema(2,&extrema);
print(extrema);
}
I also tried editing the extrema array using pointer arithmetic like the following:
**(extrema) = 0;
**(extrema+1) = 90;
But that did not work either. I really have no clue where this is going wrong and I could really use some help.
The reason you get undefined behavior is that the subscript operator [] takes precedence over the indirection operator *. The value of extrema is indexed as an array of pointers, which is incorrect, because there's only a single pointer there.
Since you are passing a pointer to a pointer, you need to put the asterisk inside parentheses:
if (quadrant == 1)
{
(*extrema)[0] = 0;
(*extrema)[1] = 90;
}
else if (quadrant == 2)
{
(*extrema)[0] = -90;
(*extrema)[1] = 0;
}
Demo on ideone.
a[b] is equal to *(a + b), but has higher precedence than the *. (And like a + b is b + a, so is a[b] equal to b[a]; and 5[a] equal to a[5]).
Thus:
*(extrema)[1] = 90;
// is equal to
*(*(extrema + 1)) = 99;
// When what you want to do is
*((*extrema) + 1) = 99;
// which is of course equal to
(*extrema)[1] = 99;
However, an even better question is: why are you using the double pointer, when it is not needed.
void get_extrema(int quadrant, int *extrema)
{
if (quadrant == 1)
{
extrema[0] = 0;
extrema[1] = 90;
}
else if (quadrant == 2)
{
extrema[0] = -90;
extrema[1] = 0;
}
}
void print(int *arr)
{
printf("%i,%i\n", arr[0], arr[1]);
}
int main(void)
{
int *extrema = (int *)malloc(2 * sizeof (int));
get_extrema(1, extrema);
print(extrema);
get_extrema(2, extrema);
print(extrema);
}

How to use a nested if else statements in a for loop in c

I'm having issues with my for statement. I'm trying to have a nested if else statement inside and I'm using pointers. I've tried everything and I've looked all over the internet. I've placed comments beside the lines with errors but if you see something else that's wrong please let me know. Thank you
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
void getinput(double*xptr, int*nptr)
{
int flag;
do
{
flag = TRUE;
printf("What is the value of x and the number of terms:");
scanf("%lf %i", xptr, nptr);
if (*nptr <= 0)
{
printf("The number of terms must be positive\n");
flag = FALSE;
}
}
while(flag == FALSE);
}
double sinHyper(double *xptr, int *nptr) {
int i;
double sum;
double ti;
i = 0;
ti = 0;
for (i = 0; i < *nptr; i = i+1)// I'm getting a Warning: comparioson between pointer and integer
{
if (i == 0)
{
sum = xptr;
} else {
ti = 2*i+1;
ti = ti*2*i;
ti = (xptr*xptr)/ti;// I'm getting a error: invalid operands to binary * (have 'double*' and 'double*')
sum = ti*sum;
}
}
return (sum);
}
void main() {
int n;
double x;
double sinhx;
getinput(&x, &n);
sinhx = sinHyper(&x, &n);
printf("For an x of %.0f with %i terms the sinh(x) is %f", x, n, sinhx);
return 0;
}
You forgot to dereference your pointers in several places.
The fact that this line compiles
sum = xptr;
should not mislead you: C lets you convert a pointer to a number with only a warning, while in most cases this is an error. This line should be
sum = *xptr;
It does not let you multiply pointers, so the expression where you square your pointer is an error:
(xptr*xptr)
You should either dereference the pointer twice, i.e. write
((*xptr)*(*xptr))
or make a separate variable for the current value of *xptr and use it instead:
const double x = *xptr;
ti = (x*x)/ti;
Note: This exercise should be purely theoretical, because sinHyper does not change *xptr or *nptr. Therefore, you should pass them as values, not as pointers:
double sinHyper(const double x, const int n) {
...
}
...
sinhx = sinHyper(x, n);

How do I use pointers correctly in my code?

Hello everyone I just started learning how to use pointers and I got stuck in my code. I need to write a code that modifies(corrects the uppercases and lowercases and finds out the year of every citizen) and sorts a list of citizens. For an example if the user entry is:
4 //just the number of citizens
lAna lanIc 1999
lana lanac 1999
laNa LaneC 1989
lAna lanOc 1999
the display must be :
18; Lanac, Lana
18; Lanic, Lana
18; Lanoc, Lana
28; Lanec, Lana
#include <stdio.h>
#include <string.h>
#include <ctype.h>
typedef struct {
char name[26];
char surname[26];
int birth;
} citizen; //the structer for the citizen
void modify(citizen *g);
int compare(citizen g1, citizen g2); //compares citizens by birth or surname or name
void sort(citizen g[], int); //insertion sort
int main()
{
int n, i;
citizen g[100];
scanf("%d", &n);
for(i = 0; i < n; i++) {
scanf("%s %s %d", g[i].name, g[i].surname, &g[i].birth);
modify(g + i);
}
sort(g, n);
for (i = 0; i < n; i++) {
printf("%2d; %s %s\n", g[i].birth, g[i].surname, g[i].name);
}
return 0;
}
void modify(citizen *g) { //here I'm having trouble
int i = 0;
//trying to correct the name
if(isalpha(*g[i].name[0])) {
*g[i].name[0] = toupper(*g[i].name[0]);
}
for(i = 1; i < strlen(*g[i].name); i++) {
*g[i].name = toupper(*g[i].name);
}
//then the surname
if(isalpha(*g[i].surname[0])) {
*g[i].surnma[0] = toupper(*g[i].surname[0]);
}
for(i = 1; i < strlen(*g[i].surname); i++) {
*g[i].surname = toupper(*g[i].surname);
}
*g[i].birth = 2017 - *g[i].birth; //finding how old is the citizen
}
int compare(citizen g1, citizen g2) {
if(g1.birth == g2.birth) {
if(!strcmp(g1.surname, g2.surname)) {
return strcmp(g1.name,g2.name);
}
else {
return strcmp(g1.surname, g2.surname);
}
}
else if (g1.birth > g2.birth) {
return 1;
}
return -1;
}
void sort(citizen g[], int n) { //insertion sort
int i, j;
citizen tmp;
for(i = 0; i < n; i++) {
tmp = g[i];
j = i;
while(j > 0 && compare(g[j-1], tmp)) {
g[j] = g[j - 1];
j--;
}
g[j] = tmp;
}
}
The basics:
In your main function this:
citizen g[100];
declares an array of 100 citizens. g is an array which is not a pointer.
In your modify function
modify(citizen *g)
g is a pointer to a citizen. It is not an array. So you're probably asking why it is legal to do this:
modify(g + i);
The reason is that, in the context of using g in an expression, it is transformed by the compiler into a pointer to its first element. We say "g decays to a pointer to its first element".
There are two ways to access the thing(s) that a pointer points to (we say "dereference the pointer"). The first is to use the * operator. If p is int* we can do
int x = *p;
If p points to an int that is in an array of ints, we can do pointer arithmetic. So we could do
int y = *(p + 3);
int z = *(p - 2);
If p points to the third element of an array that is at least size 6, y now has the same value as the sixth element and z has the same value as the first element.
The second way to dereference a pointer is to use subscript syntax. The syntax p[i] is exactly equivalent to *(p + i) and I mean exactly. Addition is commutative so p + i == i + p which means *(p + i) == *(i + p) which means (and this is legal in C) p[i] == i[p] Anyway each of the statements above can be written using subscripts
int x = p[0];
int y = p[3];
int z = p[-2];
Except to save our sanity, we tend to only use subscript syntax if p is a pointer to the first element of an array or the first element of a malloc'd block.
If p is a pointer to a struct (like your citizen struct, you can access the fields in the struct by dereferencing p and using the normal diot syntax.
int myBirth = (*p).birth;
The parentheses are necessary because the dot operator normally has higher precedence than the * operator. With *p.birth the C compiler thinks that p s a struct with a field called birth which it tries to dereference as a pointer. C provides a shortcut syntax for the (*p).birth thing which is
int myBirth = p->birth; // Exactly equivalent to (*).birth
Finally in C, you can obtain a pointer to an arbitrary object with the & operator.
int x = 0;
int* p = &x; // p is a pointer to x.
So when we say g decays to a pointer to its first element, what we mean is that the compiler transforms
modify(g + i);
to
modify(&g[0] + i);
So, you see, your modify function receives a pointer to an element of g. Looking at the first couple of lines of the function:
if(isalpha(*g[i].name[0])) {
*g[i].name[0] = toupper(*g[i].name[0]);
}
Because i is 0 at this point, `g[i].name` is the same as `(*g).name` or `g->name`. Use the last one for clarity. The `name` field is an array of chars, so `name[0]` is the first character of the name, which is what you want. You have an extra dereference with the leading * that you don't need. The above should be
if (isalpha(g->name[0])) {
g->name[0] = toupper(g->name[0]);
}
Except toupper does the isalpha check for you, so all that becomes
g->name[0] = toupper(g->name[0]);
I'll leave it to you to fix the rest of the function, except to mention the rather bad bug here:
for(i = 1; i < strlen(*g[i].surname); i++) {
*g[i].surname = toupper(*g[i].surname);
}
This actually makes no sense to me at all.
Instead of dereference pointer your way, I will give you answer here:
void modify(citizen *g) { //here I'm having trouble
int i = 0;
//trying to correct the name
//Is this really necessary?
if (isalpha(g->name[0])) {
g->name[0] = toupper(g->name[0]);
}
for (i = 1; i < strlen(g->name); i++) {
g->name[i] = toupper(g->name[i]);
}
//then the surname
//Is this really necessary?
if (isalpha(g->surname[0])) {
g->surname[0] = toupper(g->surname[0]);
}
for (i = 1; i < strlen(g->surname); i++) {
g->surname[i] = toupper(g->surname[i]);
}
g->birth = 2017 - g->birth; //finding how old is the citizen
}
I've also modify you compare function:
int compare(citizen *g1, citizen *g2) {
if (g1->birth == g2->birth) {
int resp = strcmp(g1->surname, g2->surname);
if (!resp) {
return strcmp(g1->name, g2->name);
}
return resp;
} else if (g1->birth > g2->birth) {
return 1;
}
return -1;
}

Memory Allocation in C and passing multiple numbers

I'm having a difficult time figuring out how'd I'd accomplish a task and am looking for help.
So, I need to use a function that'll find a pair of numbers (to be allocated dynamically) that meets a condition and returns a pointer to it.
Here's what I have:
int* f_cubes_sum(int n)
{
//Declaring array
int *numSet;
numSet = (int *)malloc(2); // Only two because I'm looking for a pair
//Declaring variables
int sum = 0;
int a = 0;
int b = 0;
bool results = false;
while (b < n && results == false)
{
while (a < n)
{
sum = a^3 + b^3;
if (sum == n)
{
results = true;
}
else
{
a = a + 1;
}
sum = 0;
}
if (results = false)
{
a = 0;
b = b + 1;
}
}
if (results = false)
{
a = NULL;
b = NULL;
}
numSet[0] = a;
numSet[1] = b;
free(numSet);
return numSet;
}
And in my main function, how would I access both numbers?
Thank you for your time
You are looking for a function that determines whether a number can be written a the sum of two cubes and if so, it should yield the two numbers whose cubes are summed. Basically you need:
an information on whether n can be written as a³ + b³ and
if so, the values of a and b.
You can use your approach of allocating an array of two integers and return that on success and NULL on failure. If you do so, you should allocate the array only if you have a result:
int *f_cubes_sum(int n)
{
int a, b;
// logic to work out whether a³ + b³ == n
if (a*a*a + b*b*b == sum) {
int *res = malloc(2 * sizeof(*res));
res[0] = a;
res[1] = b;
return res;
}
// no solution found
return NULL;
}
The drawback here is that the calling code has to free the returned pointer:
int *res = f_cubes_sum(2778);
if (res) {
printf("%d, %d\n", res[0], res[1]);
free(res);
}
Another approach is to pass in an array that your code has to fill and indicate success or failure with a boolean return value:
bool f_cubes_sum(int n, int res[2])
{
int a, b;
// logic to work out whether a³ + b³ == n
if (a*a*a + b*b*b == sum) {
res[0] = a;
res[1] = b;
return true;
}
// no solution found
return false;
}
Now the calling code has to provide the space for the result:
int res[2];
if (f_cubes_sum(2778, res)) {
printf("%d, %d\n", res[0], res[1]);
}
Of course, because you are always dealing with two possible result values, you could also pass pointers to these values instead of passing an array. Here's a variant of your function that does this:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
bool f_cubes_sum(int n, int *pa, int *pb)
{
int a = 0;
while (1)
{
int a3 = a*a*a;
if (a3 > n) break;
int b = cbrt(n - a3) + 0.5;
int b3 = b*b*b;
if (a3 + b3 == n) {
*pa = a;
*pb = b;
return true;
}
a++;
}
return false;
}
int main(void)
{
int a, b;
int n = 35001;
if (f_cubes_sum(n, &a, &b)) {
printf("%d^3 + %d^3 == %d\n", a, b, n);
} else {
printf("Nothing found for %d.\n", n);
}
return 0;
}
Also note what commenters have alreadey pointed out:
In C, = assigns, == compares. Unfortunately, an assignment inside an iF condition is valid C: It will assign the value and then test it, entering the clause if it isn't 0 or false. Therefore if (x = false) never enters the if clause. Switch on warnings to carch such mistakes.
The ^ operator isn't the power operator, it is the bitwise xor operator. Raising a number a to the power of b is done with the floating-point function pow(a, b). If the exponent is a known small integer, it is usually better to write the multiplication explicitly. Thus, pow(a, 3) is rendered better as a*a*a.
When allocating memory, be sure the make enough room for the desired type. Also don't use freed pointers; the memory they point to is invalid.

C Pointers and Access Violation Read Location

I'm new to C and still learning about pointers. I was just testing my understanding of pointers by trying to simulate appending to an array when I got an Access Violation Read Loaction error when using printf. This is the code:
#include <stdio.h>
#include <stdlib.h>
int arraySize(int *arrayToSize);
void changeAll(int ***a1PtrPtrPtr, int nToAdd){
int *bPtr = (int *)malloc((arraySize(**a1PtrPtrPtr) + 1) * sizeof(int));
int i = 0;
while (*(**a1PtrPtrPtr + i) != -1){
bPtr[i] = *(**a1PtrPtrPtr + i);
i++;
}
bPtr[i] = nToAdd; i++;
bPtr[i] = -1;
*a1PtrPtrPtr = &bPtr;
}
int main(void){
int a[4] = { 1, 2, 3, -1 };
int *aPtr = a;
int **aPtrPtr = &aPtr;
int ***aPtrPtrPtr = &aPtrPtr;
int n = 4;
changeAll(aPtrPtrPtr, n);
int counter = 0;
while (counter < 5){
int temp = *(*aPtrPtr + counter);
printf("%d is %d", counter, temp );
counter++;
}
return 0;
}
int arraySize(int *arrayToSize){
int sizeTemp = 0;
int i = 0;
while (arrayToSize[i] != -1){
sizeTemp++;
i++;
}
sizeTemp++;
return sizeTemp;
}
I get the error the second time I print in the while loop in main() when counter = 1. What I don't understand is that if I comment out that printf statement and look at the value of temp value in my IDE (MVSE 2013) it is exactly as I wanted and expected i.e. temp will be 1 then 2,3,4,-1.
What is going on please and thanks in advance for any help.
Firstly, in case you're wondering how this appeared to sometimes work, you really should read this stellar answer to another somewhat related question.
In short, you're saving an address to an automatic variable from inside a function, then treating said-address like it is still valid after the function returns. That the automatic variable is a pointer referring to dynamic data is irrelevant. The variable itself is no longer valid once the function expires, and thus dereferencing its use-to-be-address invokes undefined behavior:
void changeAll(int ***a1PtrPtrPtr, int nToAdd)
{
// NOTE: local variable here
int *bPtr = (int *)malloc((arraySize(**a1PtrPtrPtr) + 1) * sizeof(int));
int i = 0;
while (*(**a1PtrPtrPtr + i) != -1){
bPtr[i] = *(**a1PtrPtrPtr + i);
i++;
}
bPtr[i] = nToAdd; i++;
bPtr[i] = -1;
// NOTE: saving address of local variable here
*a1PtrPtrPtr = &bPtr;
}
With how this is setup, the quickest fix is simply this:
**a1PtrPtrPtr = bPtr;
instead of what you have. This will save the dynamic allocation result to the correct location (which is ultimately the address held in aPtr back in main()). It looks hideous (and frankly, it is), but it will work.
Best of luck.

Resources