I was wondering what is the difference between these two lines of code?
int hi;
int *hi;
In the C programming language?
Thanks!
Amit
int hi;
reserves the space for an int in memory, and each time you reference hi, you either read or write directly that int in memory space.
int *hi;
reserves the space for a pointer to an int in memory, each time hi is used, the pointer is either read or written. Meaning that you are not working with an int, only a pointer to an int - there must exist an int somewhere for the pointer to reference something workable. For instance
int hi;
int *phi;
phi = &hi; // phi references the int hi
*phi = 3; // set `hi` to 3
int hi declares the variable hi to be an integer.
int *hi declares the variable hi to be a pointer to an integer.
The first declares an integer variable, while the second declares a pointer to an integer.
Pointers are beyond the scope of a StackOverflow post, but this Wikipedia article is a starting point, and there should be at least a chapter on pointers in whatever book you're using to learn C.
hi stores the integer type value in a particular location, but
*hi stores the address of any int type variable.
Example :
int hi = 10;
int *hello = &hi;
int hi------ indicates that hi is the integer which allocates 2 bytes for it.
int *hi------ * indicates the pointer which holds the address of the variable and that variable is an integer.
both are different.one indicates the integer and the other indicates the address of the integer.
int hi;
reserve a place in the memory for an integer variable while
int *ptr;
reserve a place in the memory for a pointer which contain the memory address of other variable. you can use the pointers in different ways.
int *ptr = hi;
int *ptr;
ptr = &hi;
when you change the value of the ptr you change the address where it is pointing for but if you changed the value after de-referencing the address you are changing the value of the other variable.
*ptr = 3;
leads to change the value of hi;
a. int i;
b. int *address;
c. address = &i;
In line a an integer variable named i is declared. When this is done the compiler reserves a memory space of size sizeof(int) (it's 4 byte on my computer). If you want to refer to this memory space then you have to use pointers.
Line b declares a variable named address which has a special property. This variable doesn't holds an int but it stores the address of a variable that is of type int. Therefore, whatever value address has, it should be interpreted as the address of a variable which is of type int. Currently, the variable address doesn't hold any memory address in it as we haven't yet defined which variable's memory address it has to hold.
Line c can be read as "address is equal to the memory address of variable i". Now, the variable address stores the memory address of the int variable i.
int main(){
int a;
int &b;
b=&a;
a=10;
return 0;
}
When this code is run using a debugger I see:
a = 10 // the variable's value
b = 0x7fffffffe2fc // this is the address at which 'a' is stored.
Pointers are very powerful and you will start to use it more often once you understand it. Apart from the materials that others suggested for you to read I suggest use a debugger(gdb) and run a few programs with pointers in it and check every variable that you declared in the code. I understand things better when I have a visual picture of any problem and I think it might as well speed up your understanding of pointers.
First -int hi;
here you declaring a integer variable named "hi"
Then -int *hi;
here "hi" is a pointer which can point to a integer value
Note:int* hi and int *hi are syntactically same
Related
I am mixed up on my pointers and references. I want to create a pointer in a main function and set it to null. I would like to pass that pointer to another function that creates an array on the heap, fills it, and returns the size of the created array.
I tried to find another article about this topic but failed to find one that allocated memory from within the function. The example code below illustrates the concept but I am not writing a program to accomplish any specific task.
int fillarray(/* pointer to an array */){
// malloc the array to size n
// fill array with n elements
return n;
}
int main(){
int* array = NULL;
int size = fillarray(/* pass the pointer by reference */);
for(int i = 0; i < size; i++) printf("%d\n", array[i]);
free(array);
return 0;
}
UPDATE:
Thank you all for your comments. I learned a ton about pointers working through this problem. The code below accomplishes what I need it to. Thank you #Lundin. Your answer led me to the actual solution. Thank you #ssd as well. Your visual helped me gain some intuition on what I was looking at in the code.
int fillarray(int** array){
*array = (int*)malloc(2 * sizeof(int));
(*array)[0] = 0;
(*array)[1] = 1;
return 2;
}
int main(){
int* array = NULL;
int size = fillarray(&array);
for(int i = 0; i < size; i++) printf("%d\t", array[i]);
return 0;
}
Strictly speaking there are no "references" in C, everything is passed by value. Although the term "pass by reference" is language agnostic and really just means pass an address to the data. (C++ has a language concept called references, but it's really just glorified read-only pointers.)
So to achieve what you want, you have to pass the address of the pointer itself. That way, the function can access the pointer and set it to point at a new address. Thus declare the function as int fillarray (int**)call the function as fillarray(&array). The result of malloc needs to be assigned to where the pointer-to-pointer points at - it points at the address of the original pointer declared variable in main().
As for allocating a variable size, you will have to add an additional plain integer parameter to the function for that.
I do agree & consent Lundin's answer but to be more conceptual, I'll add the drawing below, for I had the same pain in the past understanding pointers.
The first integer pointer below (int *a) is at memory address 4c4b40 and its value is set to zero (which means this pointer a is set to null).
The second integer pointer (int *b) is at memory address 4c4b48 and its value is set to 4c4b58 (which means, this pointer points to memory address 4c4b58 with a length of integer). If that address corresponds to variable int x = 16 (hexadecimal 10 is equal to 16), then dereferencing pointer b will give you an integer value of 16 (*b = 16 because x = 16).
The third memory is another character string pointer, which points to a memory address somewhere down below.
Returning to the answer:
If you are to change the address of the first pointer (a) in order to point to the variable x, then the function you're calling needs to receive the address of the pointer (not the pointer, itself); i.e. &a instead of a, which corresponds to 4c4b40. The function called will receive the address 4c4b40 as a memory address and change its value from 000000 to 4c4b58. The function decoration, of course, will contain an int **; for, if an integer pointer is an int *, a pointer to a pointer will be an int **.
I have to questions about pointers; one theoretical and one practical.
Why, when declaring a pointer in C, must I preface the *var with a type. If a pointer is simply a variable that contains a memory address why does the compiler/language need any more information than that it is a pointer. What is the difference between an int * and a char *. Does this imply that an int * is pointing a some location that contains 2-4 bytes of memory and a char * contains only 1? I have never read anything about the underlying reasoning for why the type matters if ultimately it is a variable pointing to some hexadecimal number as evidence by %p printing them.
Secondly, given this code
int t = 10;
int *i = &t;
int *j = i;
--
*i == 10;
*j == 10;
Why is it that *j is equal to 10 instead of **j being 10? If j is a pointer to i which is a pointer to t which is 10 don't i need to double dereference the variable j? When writing this code in xcode it forces me to use *j.
So these are a few examples of confusion I have had with pointers.
The datatype is required in order to know how many bytes to read when the pointer is dereferenced.
int *i = &t;
Here, the value stored in i is the address of t.
int *j = i;
So now, the value stored in j is the value stored in i which is the address of t. If you wanted to do a double dereference, you'd need to store the address of i.
int **j = &i
why does the compiler/language need any more information than that it is a pointer
To use the pointer only, the compiler doesn't. The type void* means "a pointer to anything".
However, to use the value that is being pointed to, the compiler needs to know the type of what is being pointed to, so that it knows what can be done with it. Dereferencing a void* will cause a compiler error, unless you first cast it to a typed pointer.
Secondly, given this code
j is not a pointer to i. The assignment int *j = i; sets j to the same value as i, which is the address to t (so j would now point to t).
To make j a pointer to i, you would need to declare it as int **j = &i;
why does the compiler/language need any more information than that it is a pointer.
That's because different data types are of different size and size of data types are needed to allocate memory.
What is the difference between an int * and a char *.
int * is a pointer to int and char * is a pointer to a char.
Why is it that *j is equal to 10 instead of **j being 10? If j is a pointer to i which is a pointer to t which is 10 don't i need to double dereference the variable j?
int *j = i; tells the compiler that declare j as pointer to int and point this pointer to the memory location where pointer i points to. Therefore j is a pointer to variable t.
C is a statically typed language. There are other languages, like JavaScript for example, which are dynamically typed, where you can assign objects of different types to the same variable.
Both approaches have their advantages and disadvantages, the most important advantage of statically typed languages is that many errors can be caught at compilation.
It's a design decision.
Given pointers to char, one can do the following:
char *s = "data";
As far as I understand, a pointer variable is declared here, memory is allocated for both variable and data, the latter is filled with data\0 and the variable in question is set to point to the first byte of it (i. e. variable contains an address that can be dereferenced). That's short and compact.
Given pointers to int, for example, one can do this:
int *i;
*i = 42;
or that:
int i = 42;
foo(&i); // prefix every time to get a pointer
bar(&i);
baz(&i);
or that:
int i = 42;
int *p = &i;
That's somewhat tautological. It's small and tolerable with one usage of a single variable. It's not with multiple uses of several variables, though, producing code clutter.
Are there any ways to write the same thing dry and concisely? What are they?
Are there any broader-scope approaches to programming, that allow to avoid the issue entirely? May be I should not use pointers at all (joke) or something?
String literals are a corner case : they trigger the creation of the literal in static memory, and its access as a char array. Note that the following doesn't compile, despite 42 being an int literal, because it is not implicitly allocated :
int *p = &42;
In all other cases, you are responsible of allocating the pointed object, be it in automatic or dynamic memory.
int i = 42;
int *p = &i;
Here i is an automatic variable, and p points to it.
int * i;
*i = 42;
You just invoked Undefined Behaviour. i has not been initialized, and is therefore pointing somewhere at random in memory. Then you assigned 42 to this random location, with unpredictable consequences. Bad.
int *i = malloc(sizeof *i);
Here i is initialized to point to a dynamically-allocated block of memory. Don't forget to free(i) once you're done with it.
int i = 42, *p = &i;
And here is how you create an automatic variable and a pointer to it as a one-liner. i is the variable, p points to it.
Edit : seems like you really want that variable to be implicitly and anonymously allocated. Well, here's how you can do it :
int *p = &(int){42};
This thingy is a compound literal. They are anonymous instances with automatic storage duration (or static at file scope), and only exist in C90 and further (but not C++ !). As opposed to string literals, compound literals are mutable, i.e you can modify *p.
Edit 2 : Adding this solution inspired from another answer (which unfortunately provided a wrong explanation) for completeness :
int i[] = {42};
This will allocate a one-element mutable array with automatic storage duration. The name of the array, while not a pointer itself, will decay to a pointer as needed.
Note however that sizeof i will return the "wrong" result, that is the actual size of the array (1 * sizeof(int)) instead of the size of a pointer (sizeof(int*)). That should however rarely be an issue.
int i=42;
int *ptr = &i;
this is equivalent to writing
int i=42;
int *ptr;
ptr=&i;
Tough this is definitely confusing, but during function calls its quite useful as:
void function1()
{
int i=42;
function2(&i);
}
function2(int *ptr)
{
printf("%d",*ptr); //outputs 42
}
here, we can easily use this confusing notation to declare and initialize the pointer during function calls. We don't need to declare pointer globally, and the initialize it during function calls. We have a notation to do both at same time.
int *ptr; //declares the pointer but does not initialize it
//so, ptr points to some random memory location
*ptr=42; //you gave a value to this random memory location
Though this will compile, but it will invoke undefined behaviour as you actually never initialized the pointer.
Also,
char *ptr;
char str[6]="hello";
ptr=str;
EDIT: as pointed in the comments, these two cases are not equivalent.
But pointer points to "hello" in both cases. This example is written just to show that we can initialize pointers in both these ways (to point to hello), but definitely both are different in many aspects.
char *ptr;
ptr="hello";
As, name of string, str is actually a pointer to the 0th element of string, i.e. 'h'.
The same goes with any array arr[], where arr contains the address of 0th element.
you can also think it as array , int i[1]={42} where i is a pointer to int
int * i;
*i = 42;
will invoke undefined behavior. You are modifying an unknown memory location. You need to initialize pointer i first.
int i = 42;
int *p = &i;
is the correct way. Now p is pointing to i and you can modify the variable pointed to by p.
Are there any ways to write the same thing dry and concisely?
No. As there is no pass by reference in C you have to use pointers when you want to modify the passed variable in a function.
Are there any broader-scope approaches to programming, that allow to avoid the issue entirely? May be I should not use pointers at all (joke) or something?
If you are learning C then you can't avoid pointers and you should learn to use it properly.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm learning C programming and do not quite understand the following program, need some help with the understanding.
Question 1: What do the two asterisks do preceding *argv in the main function parameters.
Question 2: Inside the main() function, why void is followed by an asterisk? What does it do?
Question 3: &retval has the "&", does the variable "retval" point to the memory address?
Thanks for help
/** Main */
int main(int argc, char **argv) {
pthread_t thread;
void* retval;
pthread_create(&thread, NULL, thread_proc, NULL);
printf("Hello from the main thread.\n");
pthread_join(thread, &retval);
printf("Done.\n");
return 0;
}
This issue is somewhat confusing when starting to learn C.
Here are the basic principles that might help you get started:
There are only a few basic types in C:
char: an integer value with the size of 1 byte.
short: an integer value with the size of 2 bytes.
long: an integer value with the size of 4 bytes.
long long: an integer value with the size of 8 bytes.
float: a non-integer value with the size of 4 bytes.
double: a non-integer value with the size of 8 bytes.
Note that the size of each type is generally defined by the compiler and not by the standard.
The integer types short, long and long long are usually followed by int.
It is not a must, however, and you can use them without the int.
Alternatively, you can just state int, but that might be interpreted differently by different compilers.
So to summarize this:
short is the same as short int but not necessarily the same as int.
long is the same as long int but not necessarily the same as int.
long long is the same as long long int but not necessarily the same as int.
On a given compiler, int is either short int or long int or long long int.
If you declare a variable of some type, then you can also declare another variable pointing to it.
For example:
int a;
int* b = &a;
So in essence, for each basic type, we also have a corresponding pointer type.
For example: short and short*.
There are two ways to "look at" variable b (that's what probably confuses most beginners):
You can consider b as a variable of type int*.
You can consider *b as a variable of type int.
Hence, some people would declare int* b, whereas others would declare int *b.
But the fact of the matter is that these two declarations are identical (the spaces are meaningless).
You can use either b as a pointer to an integer value, or *b as the actual pointed integer value.
You can get (read) the pointed value: int c = *b.
And you can set (write) the pointed value: *b = 5.
A pointer can point to any memory address, and not only to the address of some variable that you have previously declared. However, you must be careful when using pointers in order to get or set the value located at the pointed memory address.
For example:
int* a = (int*)0x8000000;
Here, we have variable a pointing to memory address 0x8000000.
If this memory address is not mapped within the memory space of your program, then any read or write operation using *a will most likely cause your program to crash, due to a memory access violation.
You can safely change the value of a, but you should be very careful changing the value of *a.
Type void* is exceptional in the fact that it doesn't have a corresponding "value type" which can be used (i.e., you cannot declare void a). This type is used only as a general pointer to a memory address, without specifying the type of data that resides in that address.
Answer one :
char **argv mean you have a two dimension array of char.
you can access it like this :
argv[0][2]
it give you a char.
But you can access like this :
argv[0]
who give you a char *
Here, the '*' told that it's a pointer.
So it's not a char directly in your memory, but a case which will contain an address to char.
The fact to have int *; or char *; or anything * mean that you probably have an array.
Answer 2:
The void * is simple.
You have a pointer to something you don't know yet what it will be.
So a void * pointer can take address of any type of value like a char, a int, r more sophisticate type like system time (here, thread pointer).
Answer 3:
The '&' mean : take the address of this field.
So if I have
int i = 5;
printf("%i", i);
printf("%i", &i);
the first print will show the value of int : here 5.
The second will show you the address of i, here something like 0x06528A7
the fact with '&' is that you can do this :
int *ptr;
int i = 5;
ptr = &i;
you can now send your 'int *ptr' or another function, to modify it.
It will be too in the main.
Cause while modifying 'ptr', you are modifying 'i' and not a copy.
Hope it helps you!
* in c is used to declare pointers. A pointer is a variable that holds the location of, literally the address-of, a variable stored in computer memory.
So in your question void* retval; declare a void pointer. A void pointer is a special type of pointer that can be pointed at objects of any data type!
char **argv
is a pointer to a pointer to char. Actually it is a variable that holds the address of a variable that is a pointer also
char** argv is equivalent to char **argv, and roughly means
A memory address value that when accessed, contains a memory address value which
when accessed contains a memory address value which contains the first char
C uses null terminated strings, so all that is needed to know the end of a string is the first memory address where it starts. The rest of the routines then search subsequent addresses looking for the null \0 character.
C also uses null terminated lists, so all that is needed to know the end of a list is the first memory address where the list starts (assuming you know the size of the list). In this case, the list is of size sizeof(*char), or in English "the size of a pointer to char". The rest of the list traversing routines then search subsequent indexes in the list (subsequent memory offsets) until it is terminated by the null character.
Try to read it right to left, and it reads "a pointer to a pointer to a char", or in easier terms "a list of strings".
* is a notation to mark pointer You should learn about pointers in c
1)By char** argv, argv is declared as a pointer to pointer to char
2) By void*, it means a variable that can hold address of any kind of variable.
3) as retval is a pointer, it can point to a memory location. and by &retval you are getting address of the variable named retval.
& is called the address of operator.
I am trying to learn C. The reading I've been doing explains pointers as such:
/* declare */
int *i;
/* assign */
i = &something;
/* or assign like this */
*i = 5;
Which I understand to mean i = the address of the thing stored in something
Or
Put 5, or an internal representation of 5, into the address that *i points to.
However in practice I am seeing:
i = 5;
Should that not cause a mismatch of types?
Edit: Semi-colons. Ruby habits..
Well, yes, in your example setting an int pointer to 5 is a mismatch of types, but this is C, so there's nothing stopping you. This will probably cause faults. Some real hackery could be expecting some relevant data at the absolute address of 5, but you should never do that.
The English equivalents:
i = &something
Assign i equal to the address of something
*i =5
Assign what i is pointing to, to 5.
If you set i = 5 as you wrote in your question, i would contain the address 0x00000005, which probably points to garbage.
Hope this helps explain things:
int *i; /* declare 'i' as a pointer to an integer */
int something; /* declare an integer, and set it to 42 */
something = 42;
i = &something; /* now this contains the address of 'something' */
*i = 5; /* change the value, of the int that 'i' points to, to 5 */
/* Oh, and 'something' now contains 5 rather than 42 */
If you're seeing something along the lines of
int *i;
...
i = 5;
then somebody is attempting to assign the address 0x00000005 to i. This is allowed, although somewhat dangerous (N1256):
6.3.2.3 Pointers
...
3 An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant.55) If a null pointer constant is converted to a
pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
...
5 An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation.56)
...
55) The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant; see 7.17.
56) The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment.
Depending on the architecture and environment you're working in, 0x00000005 may not be a valid integer address (most architectures I'm familiar with require multibyte types to start with even addresses) and such a low address may not be directly accessible by your code (I don't do embedded work, so take that with a grain of salt).
I understand to mean i = the address of the thing stored in something
Actually i contains an address, which SHOULD be the address of a variable containing an int.
I said should because you can't be sure of that in C:
char x;
int *i;
i = (int *)&x;
if i is a pointer, than assign to it something different to a valid address accessible from you program, is an error an I think could lead to undefined behavior:
int *i;
i = 5;
*i; //undefined behavior..probably segfault
here's some examples:
int var;
int *ptr_to_var;
var = 5;
ptr_to_var = var;
printf("var %d ptr_to_var %d\n", var, *ptr_to_var); //both print 5
printf("value of ptr_to_var %p must be equal to pointed variable var %p \n" , ptr_to_var, &var);
I hope this helps.
This declares a variable name "myIntPointer" which has type "pointer to an int".
int *myIntPointer;
This takes the address of an int variable named "blammy" and stores it in the int pointer named "myIntPointer".
int blammy;
int *myIntPointer;
myIntPointer = &blammy;
This takes an integer value 5 and stores it in the space in memory that is addressed by the int variable named "blammy" by assigning the value through an int pointer named "myIntPointer".
int blammy;
int *myIntPointer;
myIntPointer = &blammy;
*myIntPointer = 5;
This sets the int pointer named "myIntPointer" to point to memory address 5.
int *myIntPointer;
myIntPointer = 5;
assignment of hard-coded addresses, is something that shouldn't be done (even in the embedded world, however there are some cases where it's suitable.)
when declaring a pointer, limit yourself to only assign a value to it with dynamiclly allocated memory(see malloc()) or with the & (the address) of a static (not temporary) variable. this will ensure rebust code, and less chance to get the famous segmentation fault.
good luck with learning c.