i have this array where i am trying to access its elements by incrementing ptr, as suggested here Trying to find different methods of accessing array elements?...i must be doing something stupid...please help me!
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
char *p1 = "Cnversions";
char *p2 = "Divided";
char *p3 = "Plain";
char *p4 = "Solid";
char *arr[3];
arr[0] = p1;
arr[1] = p2;
arr[2] = p3;
arr[3] = p4;
for(i=0;i<=3;i++)
{
printf("string at arr[%d] is: %s\n",i,*arr);
arr++;
}
return 0;
}
An array like arr is located at a specific spot in memory, so it makes no sense to increment arr (what does it mean to increment an array?)
Instead, you will need to create a pointer to the start of the array and increment the pointer:
char **ptr = arr;
for(i=0; i<4; i++) {
printf("arr[%d] = %s\n", i, *ptr);
ptr++;
}
(Note also that you need to make arr four elements big, i.e. char *arr[4], to accommodate the four string pointers you put in it.)
Remember that although we tend to think of double pointers as arrays, all the compiler sees them as are pointers. When you increment a pointer, it adds a value to the address of the pointer equal to the size of the data type it's pointing at. For example:
int *p;
p = (int *) malloc(sizeof(int));
p is pointing to an int, so the size of p's pointed data is (typically) 4 bytes. This means when you increment p, it will be pointing at a location 4 bytes greater than where it was before.
The type of arr is a char**, meaning that it's a pointer to a pointer to a char. Pointers on most machines these days are 8 bytes. So when you incrementing arr, you are effectively telling the computer to set arr to point to an address 8 bytes higher than what it was at before. In the case of arr, this is an illegal address, so you'll get some kind of crash.
Related
Using DevCpp with TDM GCC 4.9.2 on Windows 8. But I don't think the platform matters for this question.
I know that we can use a pointer to point to a single data or an array of data.
I have learned about pointer to arrays but never used it. What advantage does one have over the other?
Sample Code...
#include <stdio.h>
int main()
{
int x[2]={10,20};
int *p1= NULL; //simple pointer
int (*p2)[] = NULL; //pointer to an array, specifically
p1 = x;
p2 = &x; //removing the & gives me a warning of "assignment from incompatible pointer types".
printf("x[1] = %d\n", x[1]);
*(p1+1) = 7;
printf("x[1] = %d\n", x[1]);
(*p2)[1] = 55;
printf("x[1] = %d", x[1]);
return 0;
}
Does p1 or p2 have an advantage over the other?
They are completely different.
int *p; - is the pointer to the int
int (*p)[1]; is a pointer to the array (in this case one element only)
In your trivial example the pointer arithmetic will be the same and generated code will be the same. But they still have different types and you may get warnings when compiled.
The "advantages" you will see when your example will be less trivial:
int (*p)[100];
p++; the pointer will point to the next 100 elements int array.
Pointer to an array means a pointer which accepts address of an array.
let's say array is int arr[5],in which size of int is 4 byte.
p is a pointer to an array that accept the address of an int array.
int arr[5];
int (*p)[5];
p=&arr;//address of an array block
let's say the base address is 1000 .So after increment in p it will lead us to 1020 address,because the size of the array block is 20 bytes.
p points to 1000 address
p++;
//Now p points to 1020 not 1004.
Whereas in case of int *q, q will point to 1004 as usual.
I've just read in the book "The C Programming Language" that array is not a variable and saw that assignment of array to pointers (and vice versa) can't be done as a result. So if array is not a variable then what is it?
int numbers[] = {1,2,3}
numbers is not a variable, it is the array name which is nothing but the address of the first element in the array. To verifiy this, look at the address of numbers and the address of numbers[0] by doing this: printf("%p and %p and %p", &numbers, numbers, &numbers[0]); All the the three pointers will have the same values since numbers is nothing but the address of the first element in the array. Therefore numbers is not a variable that contain a pointer or a value since it does not have a dedicated address in the memory to store value in it.
However, look at this pointer variable:
int *pnumbers = numbers;
`printf("%p and %p and %p", &pnumbers, pnumbers, &pnumbers[0]);`
You will notice that &pnumbers has a different address in memory, and that's because pnumber has a dedicated address in the memory where it stores the address of the first element in the array numbers.
Putting the code all together:
#include <stdio.h>
main(){
int numbers[] = {1,2,3};
printf("%p and %p and %p\n", &numbers, numbers, &numbers[0]); // Address of numbers, value of numbers, first element of numbers
int *pnumbers = numbers;
printf("%p and %p and %p\n", &pnumbers, pnumbers, &pnumbers[0]); // Address of pnumbers, value of pnumbers, first element of the array pnumbers is pointing to
}
Output
0xbfb99fe4 and 0xbfb99fe4 and 0xbfb99fe4 // All three have the same address which is the address of the first element in the array
0xbfb99fe0 and 0xbfb99fe4 and 0xbfb99fe4 // The first one is different since pnumbers has been allocated a memory address to store a pointer which is the first element of the array numbers
Array is a data structure containing a number of values, all of which have the same type and array names are non-modifiable l-values(named memory locations)-- it is addressable, but not modifiable. It means that it can't be modified or can't be the left operand of an assignment operator.
int a[10] = {0};
int *p = a; //OK
a++ // Wrong
a = p; // Wrong
It's a placeholder. A symbol to represent a commonly used method of referring to a sequential section of memory. It's not a variable all by itself.
int main(int argc, char** argv)
{
int array[10];
int value'
int* pointer;
value = array[0]; // Just fine, value and array[0] are variables
array[0] = value; // Just fine, value and array[0] are variables
pointer = &array[0]; // Just fine, &array[0] is an address
pointer = array; // Also just fine
//Because the compiler treats "array" all by itself as the address of array[0]
//That is: array == &array[0]
&array[0] = pointer // ERROR, you can't assign the address of something to something else.
array = pointer; // ERROR, array is not a variable, and cannot be assigned a value.
//Also bad, but technically they compile and could theoretically have their use
pointer = value;
pointer = array[0];
array[0] = pointer;
//Intermixing pointers and non-pointer variables is generally a bad idea.
}
array is often treated like a variable because it represents the adddress of (the first item in) that block of memory. But it's not a variable. It doesn't have it's own memory to store anything. People set pointers equal to 'array' because it's a handy convention, compilers know what that means, and it's pretty common.
array is a sequence of elements of the same type. if you assign a pointer to an array, pointer will point to the address of first variable from an array.
int a[10];
int *p;
int *p2;
p = a;
p2 = &a[0];
printf("%d\n", p == p2);
output:
1
I've just read in the book "The C Programming Language" that array is not a
variable and saw that assignment of array to pointers (and vice versa)
Vice versa is allowed... An array is like a constant pointer (you cant change the address it is pointing to). However, you can assign that address to a pointer.
#include <stdio.h>
int main()
{
int x[3] = {1, 2, 3};
int *p = x;
p[0] = 50;
printf("%d", x[0]);
}
I am a total beginner to C so please, work with my ignorance. Why does a normal pointer
int* ptr = &a; has two spaces in memory (one for the pointer variable and one for the value it points to) and an array pointer int a[] = {5}; only has one memory space (if I print out
printf("\n%p\n", a) I get the same address as if I printed out: printf("\n%p\n", &a).
The question is, shouldn't there be a memory space for the pointer variable a and one for its value which points to the first array element? It does it with the regular pointer int* ptr = &a;
It's a little unclear from your question (and assuming no compiler optimization), but if you first declare a variable and then a pointer to that variable,
int a = 4;
int *p = &a;
then you have two different variables, it makes sense that there are two memory slots. You might change p to point to something else, and still want to refer to a later
int a = 4;
int b = 5;
int *p = &a; // p points to a
// ...
p = &b; // now p points to b
a = 6; // but you can still use a
The array declaration just allocates memory on the stack. If you wanted to do the same with a pointer, on the heap, you would use something like malloc or calloc (or new in c++)
int *p = (int*)malloc(1 * sizeof(int));
*p = 4;
but of course remember to free it later (delete in c++)
free(p);
p = 0;
The main misunderstanding here is that &a return not pointer to pointer as it expected that's because in C language there some difference between [] and * (Explanation here: Difference between [] and *)
If you try to &a if a was an pointer (e.g. int *a) then you obtain a new memory place but when your use a static array (i.e. int a[]) then it return address of the first array element. I'll also try to clarify this by mean of the next code block.
#include <stdio.h>
int main(int argc, char *argv[])
{
// for cycles
int k;
printf("That is a pointer case:\n");
// Allocate memory for 4 bytes (one int is four bytes on x86 platform,
// can be differ for microcontroller e.g.)
int c = 0xDEADBEEF;
unsigned char *b = (unsigned char*) &c;
printf("Value c: %p\n", c);
printf("Pointer to c: %p\n", &c);
printf("Pointer b (eq. to c): %p\n", b);
// Reverse order (little-endian in case of x86)
for (k = 0; k < 4; k++)
printf("b[%d] = 0x%02X\n", k, b[k]);
// MAIN DIFFERENCE HERE: (see below)
unsigned char **p_b = &b;
// And now if we use & one more we obtain pointer to the pointer
// 0xDEADBEEF <-- b <-- &p_b
// This pointer different then b itself
printf("Pointer to the pointer b: %p\n", p_b);
printf("\nOther case, now we use array that defined by []:\n");
int a[] = {5,1};
int *ptr = &a;
// 'a' is array but physically it also pointer to location
// logically it's treat differ other then real pointer
printf("'a' is array: %x\n", a);
// MAIN DIFFERENCE HERE: we obtain not a pointer to pointer
printf("Pointer to 'a' result also 'a'%x\n", &a);
printf("Same as 'a': %x\n", ptr);
printf("Access to memory that 'a' pointes to: \n%x\n", *a);
return 0;
}
This is very simple. In first case,
int* ptr = &a;
you have one variable a already declared and hence present in memory. Now you declare another variable ptr (to hold the address, in C variables which hold address of another variable are called pointers), which again requires memory in the same way as a required.
In second case,
int a[] = {5};
You just declare one variable (which will hold a collection of ints), hence memory is allocated accordingly for a[].
In this expression, int* p = &a; p has only one memory location, of the WORD size of your CPU, most probably, and it is to store the address (memory location) of another variable.
When you do *p you are dereferencing p, which means you are getting the value of what p points to. In this particular case that would be the value of a. a has its own location in memory, and p only points to it, but does not itself store as content.
When you have an array, like int a[] = {5};, you have a series (or one) of memory locations, and they are filled with values. These are actual locations.
Arrays in C can decay to a pointer, so when you printf like you did with your array, you get the same address, whether you do a or &a. This is because of array to pointer decay.
a is still the same location, and is only that location. &a actually returns a pointer to a, but that pointer sits else where in memory. If you did int* b = &a; then b here would not have the same location as a, however, it would point to a.
ptr is a variable containing a memory address. You can assign various memory addresses to ptr. a is a constant representing a fixed memory address of the first element of the array. As such you can do:
ptr = a;
but not
a = ptr;
Pointers point to an area in memory. Pointers to int point to an area large enough to hold a value of int type.
If you have an array of int and make a pointer point to the array first element
int array[42];
int *p = array;
the pointer still points to a space wide enough for an int.
On the other hand, if you make a different pointer point to the whole array, this new pointer points to a larger area that starts at the same address
int (*q)[42]; // q is a pointer to an array of 42 ints
q = &array;
the address of both p and q is the same, but they point to differently sized areas.
Pointer1 points to 5.
Pointer2 points to 3.
I want to multiply 5*3, but I only have the pointers. How would I do this in C?
Also, what does uint32_t *pointer mean when:
pointer[2] = {1, 2};
I do not know what is so hard for the answerers to understand about this question. It is obviously about dereferencing pointers.
This is how you display the contents of the pointer that it is pointing to:
#include <stdio.h>
int main(void)
{
int num1 = 5;
int num2 = 3;
int* num1_ptr = &num1;
int* num2_ptr - &num2;
int sum = *num1_ptr * *num2_ptr;
printf("%d\n", sum);
return 0;
}
*num1_ptr and *num2_ptr takes your pointers and references what the contents of that memory address.
I can't answer the first half of your question without more information, but uint32_t* pointer is simply a pointer to an unsigned 32-bit integer value (unsigned int and uint32_t are usually equivalent types, depending on your compiler).
If I see a declaration that simply reads uint32_t* pointer without more information I'm going to assume it's a pointer to a single value, and that using the indexing operator [n] on such a pointer is basically overflowing the single-element-sized buffer. However if the pointer is assigned the result from an array or buffer function (e.g. malloc, calloc, etc) then using the indexing operator is fine, however I would prefer to see uint32_t pointer[] used as the declaration as it makes it much easier to determine the developer's intent.
uint32_t *pointer is just a pointer with garbage value unless you point it to something.
pointer[0] = 1;
pointer[1] = 2;
is only valid if you have earlier pointed it to some array of type uint32_t with atleast size two or to a block containing uint32_ts defined using malloc as follows:
uint32_t *pointer;
pointer = (uint32_t*)malloc(sizeof(int*SIZE); //SIZE > 2 here
or
uint32_t array[10];
pointer = & array[0]; // also, pointer = array; would also work.
int main(void)
{
int variableA = 5;
int variableB = 3;
int* ptr1 = &variableA; // Pointer1 points to 5.
int* ptr2 = &variableB; // Pointer2 points to 3.
int answer;
answer = (*ptr1) * (*ptr2); // I want to multiply 5*3, but I only have the pointers.
// Answer gets set to [value stored at ptr1(5)] MultipliedBy [value stored at ptr2(3)]
}
Your misconception is that pointers do not refer to values, such as 5 and 3.
pointers refer to variables, such as variableA and variableB; those variables have values which can be accessed and changed via the pointer.But the pointer only refers to the variable, not directly to the value behind it.
Please help me understand the programs below.
#include<stdio.h>
int main()
{
int a[7];
a[0] = 1976;
a[1] = 1984;
printf("memory location of a: %p", a);
printf("value at memory location %p is %d", a, *a);
printf("value at memory location %p is %d", &a[1], a[1]);
return 0;
}
&a[1] and &a+1. Are they same or different?
#include <stdio.h>
int main()
{
int v[10];
int **p;
int *a[5];
v[0] = 1234;
v[1] = 5678;
a[0] = v;
a[1] = v+1;
printf("%d\t%d\t%d\t%d\n", *a[0],*a[1],a[0][0],**a);
printf("%d\n", sizeof(v));
return 0;
}
I wanted to know how *a[5] is represented in memory. Is *a a base pointer that points to a[0],a[1],a[2],a[3],a[4]?
#include<stdio.h>
int main()
{
int v[10];
int **p;
int (*a)[10];
a=&v;
printf("%d\n",*a);
return 0;
}
a=v; // gives error why? does v here decay into *v. Then does &v get decayed into (*)[]v? & means const pointer. Here, how is it possible to set a const pointer to a non-const pointer without a typecast?
Where does the array get stored in the memory. Does it get stored onto the data segment of the memory.
#include<stdio.h>
int main()
{
int carray[5]={1,2,3,4,5};
printf("%d\n",carray[0]);
printf("%d\t%d\t%d\n",sizeof(carray),sizeof(&carray),sizeof(&carray[0]));
return 0;
}
EDITED:
I have gone through some of the articles which stated that the only two possible situations where an array name cannot be decyed into pointer is the sizeof and &. But in the above program sizeof(&carray) gives the size as 4. and &carray decays into (*)[]carray as its an rvalue.
Then the statement that array name cannot get decayed into pointers on two conditions sizeof and & becomes false here.
&a[1] and &a+1. Are they same or different?
Different. &a[1] is the same as (a+1). In general, x[y] is by definition equivalent to *(x+y).
I wanted to know how *a[5] is represented in memory. Does *a is a base
pointer that points to a[0],a[1],a[2],a[3],a[4].
In your second example, a is an array of pointers. *a[i] is the value of the object, the address of which is stored as the ith element in your array. *a in this case is the same as a[0], which is the first element in your array (which is a pointer).
a=v //why this gives error
Because a (in your last example) is a pointer to an array. You want to assign to a, then you need to assign the address of the array v (or any other array with correct dimensions);
a = &v;
This is very good that you've commited to understanding things, but nothing will help you better than a good C book.
Hope this helps.
Stuff you are gonna need to know when dealing with pointers is that:
int *a and int a[]
is a declaration of an Array, the only diffrence is that in a[] youre gonna have to declare its constant size, *a gives you flexability, it can point at an array size 1 to infinity
int *a[] and int **a
is a declaration of an Array of Array,sometimes called Matrix, the only diffrence is that in *a[] youre gonna have to declare how many Arrays a[] gonna contain pointers of, **a gives you flexability, it can point at any Array of arrays that you want it to be assigned to.
IN GENERAL:
When adding & to a variable, your adding a * to its Type definition:
int a;
&a -> &(int)=int*
when adding * to a variable, you decrase a * from its Type definition
int *a;
*a -> * (int * )=int
int *a;
&a - the Address given to the pointer a by the system(pointer of pointer = **a)
&a+1 - the Address to the beginning of the array + 1 byte
&a[1] == &(a+1) - the Address to the beginning of the array + 1 size of int
int **a;
*a == a[0] - the Address of the first Array in the array of arrays a
*a[0]==a[0][0] - the first int of first array
int *a, b[5];
*a=*b - ERROR because a points at garbage to begin with
a=b - a points at array b
ask me what else you want to know and ill edit this answer.