Pointer as parameter in C - c

The code doesn't work in my Xcode compiler. It says *&point expected '('. I really don't know what goes wrong. It should have worked.
#include<stdio.h>
#include<stdlib.h>
void transformCopy(int *point);
void transformTrue(int *&point);
int main(){
int *a,*b,i=0;
transformTrue(a);
transformCopy(b);
for(i=0;i<5;i++) {a[i]=i;}
for(i=0;i<5;i++){printf("%d ",a[i]);}
printf("\n");
for(i=0;i<5;i++) {b[i]=i;}
for(i=0;i<5;i++){printf("%d ",b[i]);}
printf("\n");
return 0;
}
void transformCopy(int *point){
point=(int*)malloc(5*sizeof(int));
}
void transformTrue(int *&point){
point=(int*)malloc(5*sizeof(int));
}

*&point expected '('.
References do not exist in C ( void transformTrue(int *&point) ), this is C++ code, not C
If you want to have the equivalent in C you have to use void transformTrue(int **point) and you have to call transformTrue(&a);
If I change your code to do in C what it is done in C++ (see comments) :
#include<stdio.h>
#include<stdlib.h>
void transformCopy(int *point);
void transformTrue(int ** point); /* ** rather than *& */
int main(){
int *a,*b = 0,i=0;
transformTrue(&a); /* &a rather than just a */
transformCopy(b);
for(i=0;i<5;i++) {a[i]=i;}
for(i=0;i<5;i++){printf("%d ",a[i]);}
printf("\n");
for(i=0;i<5;i++) {b[i]=i;}
for(i=0;i<5;i++){printf("%d ",b[i]);}
printf("\n");
return 0;
}
void transformCopy(int *point){
point=(int*)malloc(5*sizeof(int));
}
void transformTrue(int ** point){ /* ** rather than *& */
*point=(int*)malloc(5*sizeof(int)); /* *point = rather than point = */
}
transformTrue(&a) modifies the value of a, but transformCopy(b); does nothing except locally (and a memory leak) and back in main the value of b is still 0, the program will crash when you will try to write in invalid addresses
one possibility is to change transformCopy like that :
int * transformCopy(){
return (int*)malloc(5*sizeof(int));
}
and of course the call to have b = transformCopy();

Related

How to point to a pointer of a pointer

I'm writing a program that can modify rows and cols from a function of a function. I don't understand how to do pointer of a pointer.
void changeNum(int*setRows, int *setCol)
{
changeNum2(*setRows,*setCol);
}
void changeNum2(int*setRows, int *setCol)
{
*setRows=5;
*setCol=5;
}
int main() {
int*row=10;
int* col=10;
changeNum(&row,&col);
printf("%d %d",row,col);
return 0;
}
First
int*row=10;
int* col=10;
This is wrong. Assigning hardcoded address. You don't want this
int row=10;
int col=10;
How to get the address of the row and col?
&row and &col.
How to pass it to function?
Call it, changeNum(&row,&col);
void changeNum(int*setRows, int *setCol)
{
...
}
How to pass pointer to pointer?
void changeNum(int*setRows, int *setCol)
{
chnageNum2(&setRows, &setCol);
}
ChangeNum2 how it would change value?
void chnageNum2(int **setRows, int **setCol){
**setRows = 110;
**setCol = 110;
}
Can we do the same change using changeNum() only?
Yes we can do that.
void changeNum(int*setRows, int *setCol)
{
*setRows = 110;
*setCol = 110;
}
Definitely check this. Grab a book. It will help a lot.
The complete code will be
void changeNum(int*setRows, int *setCol)
{
changeNum2(&setRows,&setCol);
}
void changeNum2(int**setRows, int **setCol)
{
**setRows=5;
**setCol=5;
}
int main(void) {
int row=10;
int col=10;
changeNum(&row,&col);
printf("%d %d",row,col);
return 0;
}
#include <stdio.h>
void changeNum(int*, int*);
void changeNum2(int*, int*);
void changeNum(int* setRows, int *setCol) {
changeNum2(setRows,setCol);
}
void changeNum2(int* setRows, int *setCol) {
*setRows=5;
*setCol=5;
}
int main() {
int row=10;
int col=10;
changeNum(&row, &col);
printf("%d %d\n", row, col);
return 0;
}
It takes sometime to grasp that every C function parameter is passed by value. So you can safely pass setRows pointer to the second function simply by its value.
Also, it's necessary to declare previously the function changeNum2, I've included the declaration without parameter names to clarify it's possible.
I strongly recommend reading this book: https://en.wikipedia.org/wiki/The_C_Programming_Language, specially chapter 5 (Pointers and arrays).
You can find a PDF copy easily. It's where I finally learned this concept.

Printing an int in C

I am trying to print an int a before and after calling a set function to set the value of a. I am doing this in C. When I compile it I have no errors but when I attempt to run it, I get a segmentation fault.
Here is what I have so far:
#include <stdio.h>
int main(){
int* a;
printf("%d",*a);
set(10);
printf("%d", *a);
return 0;
}
int set(int*a, int val){
*a = val;
return *a;
}
int main(){
int* a;
printf("%d",*a);
What you have there is a pointer to an int rather than an actual int.
And, while that's the correct way to print the int it points to, unfortunately it points to an arbitrary memory location which is why you're crashing.
You are not allowed to dereference arbitrary pointers, they have to point to something valid, such as if you begin your code with:
int main(){
int target_of_a = 42;
int *a = &target_of_a;
printf ("%d", *a);
In addition, you probably should be calling set with something like:
set (a, 10);
something the compiler would generally warn you about though, in this case, it would probably just say it didn't know about set at the time you called it. If it had known, it could have told you about the parameter mismatch.
One way for you to acheive that is to ensure you have a prototype defined for the function before you call it:
int set(int*,int);
or just move the function to before main. With all those changes (and a bit of a general tidy up), you'd end up with:
#include <stdio.h>
int set (int *a, int val) {
*a = val;
return *a;
}
int main (void) {
int target_of_a = 42;
int *a = &target_of_a;
printf ("%d\n", *a);
set (a, 10);
printf ("%d\n", *a);
return 0;
}
The wisdom of returning the variable you're changing is also debatable but there are situations where that might be useful (such as if you want to us it immediately without another statement: printf ("%d\n", set (a, 10)); for example) so I've left that as is.
I should also mention that it's a little unusual to artificially create a pointer variable in a situation like this.
Now it may be that your code is just a simplification of some more complex scenario where you already have a pointer but, if not, the usual way to do this would be to just have the int itself and just use & to create one on the fly:
#include <stdio.h>
int set (int *a, int val) {
*a = val;
return *a;
}
int main (void) {
int a = 42;
printf ("%d\n", a);
set (&a, 10);
printf ("%d\n", a);
return 0;
}
This code should work:
#include <stdio.h>
#define FIRST_VALUE 20
#define SECOND_VALUE 10
int main(){
int a = FIRST_VALUE; /* Declare a as an int variable. */
printf("Before set: a = %d\n",a); /* Print the first value. */
set(&a, SECOND_VALUE); /* Pass the ADDRESS of a to set. */
printf("After set: a = %d\n", a); /* Print the new value of a. */
return 0;
}
int set(int*a, int val){
*a = val;
return *a;
}
Note that the variable a in main() is not the same as the variable a in set(); you have to pass a pointer to a to set() in order for set() to operate on it.
Try this:
And remember, all functions before the main() (if you're using only one file)
Take a read on value and reference params.
#include <stdio.h>
int set(int* a, int val){
*a = val;
}
int main(){
int a = 2;
printf("%d\n", a);
set(&a, 10);
printf("%d\n", a);
return 0;
}

Why am I not able to access values that were stored in another function?

Basically, why does it not just print the integers that are entered. Right now it just prints garbage value, but I do not know why it cannot access the values stored after it leaves the function. It only seems to get messed up after leaving the getIntegersFromUser function. If I run the for loop in the getIntegers function it does it properly, but why not in the main function?
Thanks in advance for your help.
#include <stdio.h>
#include <stdlib.h>
void getIntegersFromUser(int N, int *userAnswers)
{
int i;
userAnswers =(int *)malloc(N*sizeof(int));
if (userAnswers)
{ printf("Please enter %d integers\n", N);
for (i=0;i<N; i++)
scanf("%d", (userAnswers+i));
}
}
int main()
{
int i, M=5;
int *p;
getIntegersFromUser(M, p);
for (i=0;i<5;i++)
printf ("%d\n", p[i]);
return 0;
}
Also, this is a homework question, but it's a "Bonus Question", so I'm not trying to "cheat" I just want to make sure I understand all the course material, but if you could still try to give a fairly thorough explanation so that I can actually learn the stuff that would be awesome.
Pointers are passed by value. The function is using a copy of your pointer, which is discarded when the function ends. The caller never sees this copy.
To fix it, you could return the pointer.
int *getIntegersFromUser(int N)
{
int *userAnswers = malloc(...);
...
return userAnswers;
}
/* caller: */
int *p = getIntegersFromUser(M);
Or you could pass your pointer by reference so the function is acting on the same pointer, not a copy.
void getIntegersFromUser(int N, int **userAnswers)
{
*userAnswers = (int *) malloc(N*sizeof(int));
...
}
/* caller: */
int *p;
getIntegersFromUser(N, &p);

C function (without parameters) call with parameters

I'm wondering something like this is possible:
// declaration
void func();
int main()
{
int ar[] = { 1, 2, 3 };
func(ar); // call with parameter
return 1;
}
void func() // no parameters
{
// do something
}
Can someone explain me this and especially how can I access ar in func()?
In C (not C++), a function declared as func() is treated as having an unspecified number of untyped parameters. A function with no parameters should be explicitly declared as func(void).
A hack would be to exploit the GCC calling convention.
For x86, parameters are pushed into stack. Local variables are also in the stack.
So
void func()
{
int local_var;
int *ar;
uintptr_t *ptr = &local_var;
ptr += sizeof(int *);
ar = (int *)ptr;
May give you the array address in ar in x86.
For x86_64, the first parameter is stored in rdi register.
void func()
{
uintptr_t *ptr;
int *ar;
asm (
"movq %%rdi, %0"
:"=r"(*ptr)
:
:"rdi");
ar = (int *)ptr;
May give you the array address in ar in x86_64.
I have not tested these code myself and you may be to fine tune the offsets yourself.
But I am just showing one possible hack.
If you want to use any function with no parameters with any return type, it should be declared as (In C)
return_type func(void). It is only generic way of function declaration.
But any how, for your question , it possible to access but not generic..Try this program...
#include<stdio.h>
int *p;
void func();
int main()
{
int ar[] = { 1, 2, 3 };
p=ar;
printf("In main %d\n",ar[0]);
func(ar); // call with parameter
printf("In main %d\n",ar[0]);
return 1;
}
void func() // no parameters
{
printf("In func %d \n",*p);
*p=20;
}
Even this program works fine, it is not generic way and also is undefined.
if you declare function like void func (void) ,it will not work.
You can't access ar in func(), since you dont have a reference to it in func().
It would be possible if ar would be a global var or you have a pointer on it.
So that you can do something with func(), you need to pass it the input data you'll work with.
First you must declare the function properly :
// declaration
void func(int []);
The define it :
void func( int a[] )
{
// do something
printf ("a[0] = %d\n", a[0]);
}
Full code :
#include <stdio.h>
// declaration
void func(int []);
int main()
{
int ar[] = { 1, 2, 3 };
func(ar); // call with parameter
return 1;
}
void func( int a[] )
{
// do something
printf ("a[0] = %d\n", a[0]);
}
This will display :
a[0] = 1
You can implement something like this.
void func(int *p, int n);
int main()
{
int ar[] = { 1, 2, 3 };
func(ar, sizeof (ar)/sizeof(ar[0]) ); // call with parameter
return 1;
}
void func(int *p, int n) // added 2 parameters
{
int i=0;
for (i=0; i<n; ++i){
printf ("%d ", p[i]);
}
}

why does the position of "int i;" matters in this case?

I'm teaching myself C since my uni seems to be obsessed with java, so im writing a stack implementation of type int (ill worry about making it generic later). I came across an error that makes not sense to me, missing ';' before 'type'. As far as i can tell my syntax is right, if it is not please do tell. Anyways here is my code:
stack.h
typedef struct{
int *elements;
int size;
int capacity;
}Stack;
void newStack(Stack *s);
void delStack(Stack *s);
void pushToStack(Stack *s, int value);
int popFromStack(Stack *s);
stack.c
#include "stack.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
void newStack(Stack *s){
s->size = 0;
s->capacity = 4;
s->elements = (int*) malloc(4 * sizeof(int));
assert(s->elements != NULL); // allocation worked?
}
void delStack(Stack *s){
free(s->elements);
}
void pushToStack(Stack *s, int value){
if(s->size == s->capacity){
s->size *= 2;
s->elements = (int *) realloc(s->elements, s->size * sizeof(int));
assert(s->elements !=NULL); //reallocation worked?
}
s->elements[s->size] = value;
s->size++;
}
int popFromStack(Stack *s){
assert(s->size>0);
s->size --;
return s->elements[s->size];
}
int main()
{
Stack s1;
newStack(&s1);
int i;
for(i=0; i<3; i++){
pushToStack(&s1, i);
printf("%d ", i);
}
printf("\n");
for(i=0; i<3; i++){
printf("%d ", popFromStack(&s1));
}
delStack(&s1);
getchar();
return 0;
}
The error occurs in main, on the int i; line, but if i move the line up the error goes away and the program runs flawlessly. I want to know why.
CAUSES ERROR:
newStack(&s1);
int i;
NO ERROR:
int i;
newStack(&s1);
PS: just in case it matters.. im using MS Visual Studio 2010
Visual Studio is stuck in a time loop somewhere before 1998, back when the standard mandated that all declarations should be at the beginning of a block.
This was changed in C99, and MS does say it supports the most popular features. Sadly this is not one of them.
In C you must declare all variables at the beginning of your scope. So you can't declare i after your newStack call.
In C89 declarations are made at the top of the scope and thus before any other function call.
However this restriction was removed in C99.

Resources