void main()
{
int (*d)[10];
d[0] = 7;
d[1]=10;
printf("%d\n",*d);
}
It should print 10 but compiler is showing error such as follows:
test.c:4:7: error: incompatible types when assigning to type ‘int[10]’ from type ‘int’
Note that I have included some errors , not all.
As noted by chris, d is a pointer to an array. This means you use the variable improperly when you access it, but also that you will access random memory unless you assign d to point to a valid array.
Change your program as follows:
int main(void)
{
int (*d)[10]; /* A pointer to an array */
int a[10]; /* The actual array */
d = &a; /* Make `d` point to `a` */
/* Use the pointer dereference operator (unary prefix `*`)
to access the actual array `d` points to */
(*d)[0] = 7;
(*d)[1] = 10;
/* Double dereference is okay to access the first element of the
arrat `d` points to */
printf("%d\n", **d);
return 0;
}
In C, [] is the same as *, the pointer syntax. Thus the following lines are the same:
int** array2d1;
int* array2d2[];
int array2d3[][];
To relate to a closer example, the main function has the following popular forms:
int main(int argc, char** argv){ ... }
or
int main(int argc, char* argv[]){ ... }
Thus
int (*d)[10]
is the same as
int* d[10]
which is the same as
int** d;
int firstArray[10];
d = &firstArray;
Effectively, you are creating a pointer to a pointer (which is a pointer to an array) and allocating the first pointer to an array that 10 elements. Therefore, when you run the following lines:
d[0] = 7;
d[1] = 10;
You are assigning the 1st array's address to 7 and the second array's address to 10. So as Joachim has mentioned, to assign values, you need to deference twice:
(*d)[0] = 7
(*d)[1] = 10
Which says "Assign 7 to the 0th index at the value pointed by d". I hope that makes sense?
d is a pointer to an array of 10 ints.
int (*d)[10] is the declaration for a point to an array of 10 ints.
vs.
int *d[10], which is an array of 10 int pointers.
For more complex syntax like this (usually involving pointers), I use cdecl to help me decode it.
It's used in this form
int d[10]
I guess you are mistaken that d must be a "kind of pointer" and therfor you put an * before the d.
But that's not what you want. You wan to name an array of integer and the notation for that is seen above.
Concept of pointer can get confusing sometimes in C.
Consider an array int d[6] = {0,1,2,3,4,5}
Then, *d is equivalent to d[0]. d is itself an pointer to an array and *d dereferences that pointer and gives us the value.
Hence, following code would print the same values:
int main()
{
int (d)[10];
*d = 7;
*(d + 1)=10;
printf("%d\n",*d);
printf("%d\n",d[0]);
return 0;
}
result:
7
7
Please see http://codepad.org/LYY9ig1i.
If you change your code as follows:
#include<malloc.h>
int main()
{
int *d[10]; //not (*d)[10]
d[0] = (int *)malloc(sizeof(int *) * 10);
d[0][0] = 7;
printf("%d\n",d[0][0]);
return 0;
}
Hope this helps you!
Related
I have this code:
#include <stdio.h>
int main(void) {
int b[] = {1,2,3};
int *a = b; //works
int c = 1;
int *d = c; //doesn't work
}
Why is it that it works to initialize the pointer with an array but not an int?
int *d = c; it does work. It is simply converting the integer number held in c into a pointer. The compiler will issue the warning (unless you cast explicitly).
You can use it, for example, to read from a particular address of memory.
unsigned read_from_memory_address(unsigned address)
{
unsigned *x = (unsigned *)address;
return *x;
}
Of course, how this function will behave (or what type address should have) is implementation defined.
Pointers keep references to objects. If you want pointer to reference an integer variable you need to supply the reference (address) of this variable.
int *x = &c;
Arrays in expressions decay to pointer to first element of the array. That is why you do not need to use & in front of the array (you can, but the pointer will have a different type - in this case pointer to array).
int array[3];
int *x = array; //decays to pointer to first element
int (*y)[3] = &array; //pointer to array of 3 `int` elements
#include <stdio.h>
int main(void)
{
typedef struct{
int a;
} cool;
cool x;
(&x)->a = 3;
x.a = 4;
}
I was wondering if the (&x)-> a does the same thing as the x.a. I coded both of them up, and it seemed that both of them changed the value of x.a. I know it must be a pointer on the left side of ->, but the (&x) seems to work without problem. Printing out x.a works for both of them, and gives me the correct answer. I looked up a lot about pointers, linked list, and structures and am still not able to find out the answer. Would it be possible to get an explanation? Thank you!
The -> operator expects a pointer on the left hand side. &x returns the address of x so it satisfies that requirement (even if it is totally redundant). To think about it another way...
cool *y = x;
y->a = 3;
The . operator expects a stack allocated struct on the left hand side. x is that, so x.a works fine.
You can also go the other way, if you have a pointer y you can dereference it with *y and use . on it: (*y).a. This is also totally redundant.
The & prefix operator returns the memory address of whatever object you put it in front of.
This means that you have to put it in front of objects that actually have a memory address. For example, literals and temporary expression results don't necessarily have an address. Variables declared with register storage class don't have an address, either.
Thus:
int i = 5;
&i; // works
&5; // Nope!
&(i + 1); // Nope!
&i + 1; // Works, because &i has higher precedence than +1.
So what does the address of an object give you? It is a pointer to the object. This is how you can do dynamic memory allocation using the heap. This is where functions like malloc() come in. And this is how you can build arbitrarily large data structures.
In C, arrays are represented as pointers. So arrays and pointers are often used interchangeably. For example:
char buffer[100]; // array
strcpy(buffer, "hello"); // strcpy is declared to take (char *, const char *)
The opposite of the address_of operator is the * dereference operator. If I declare a pointer to something, I can get "what it points at" using this syntax:
int i = 5;
int *pi = &i; // pointer to int. Note the * in the declaration?
i + i; // 10
i + *pi; // Also 10, because pi "points to" i
In the case where you have an aggregate type like a struct or union, you would have to do something like this:
struct {
int a;
} s;
s.a = 5;
/* ??? */ ps = &s; // pointer to s
s.a; // 5
(*ps).a; // Also 5, because ps points to s.
ps->a; // 5, because a->b is shorthand for (*a).b
This only works, of course, if you have a pointer to an object that CAN use the .member and that has an appropriately named member. For example, you can't do this:
i = 5;
pi = &i;
pi->a; // WTF? There is no i.a so this cannot work.
If you have a pointer, you can take the address of it. You then have a pointer to a pointer. Sometimes this is an array of pointers, as with the argv array passed to main:
int main(int argc, const char *argv[]);
int main(int argc, const char **argv); // Effectively the same.
You can do weird stuff with pointers to pointers:
int i = 5;
int j = 100;
int * pij;
for (pij = &i; i < j; ) {
if (i & 1) {
*pij *= 2;
pij = &j;
}
else {
i += 1;
*pij -= 1;
pij = &i;
}
}
Note: I have no idea what that code does. But it's the kind of thing you can wind up doing if you're working with pointers.
I have a two dimensional array like this:
void getC(int **p)
{
*p = &c[0][0];
}
int c[10][10];
int *a;
getC(a);
a[0][0];
it says error: no match for 'operator[]' in `a[0][0];` what is the problem and how to fix it?
You're compiling a C program with a C++ compiler. Watch out!
You need to put the definition of c above the getC function (or provide a forward declaration).
You have statements outside of a function, which isn't allowed in C. Wrap the int *a and subsequent lines with int main(void) { ... }
You need a & to make your getC() call legal - you're passing an int *, but it expects int **:
getC(&a);
The statement a[0][0] has no effect, and is anyway wrong since a is just an int *; you can't dereference it twice.
You should probably get a beginner C book and start working through it.
Essentially you are sort of downgrading the array/pointer from an int (*)[10] (pointer to array of 10 int) to a simple int pointer, by just returning the address of the first element of the 2dim array. While this is techically correct (the address of one element of the 2dim array is of course an int*), the information about the structure/layout of the ints in the array is lost, so the resulting a-ptr doesn't now anything about the fact that the int was part of a [10][10] structure.
In your case, the only way to get to the array elements would be to multiply your way through the int arrays, based on your own knowledge that at address a there are 100 ints organized 10x10:
int *a;
getC(&a);
...= a[10*x + y]; // equivalent of c[x][y];
.
However, essentially, the correct way (completely preserving types) would be
int c[10][10];
void getC(int (**p)[10]) // pointer to pointer to array of 10 ints
{
*p = c; // c itself can seamlessly change into a pointer to one sub-element
// (i.e. pointer to array of 10)
}
int main()
{
int (*a)[10]; // pointer to array(s) of 10 ints
int q;
getC(&a);
q= a[9][9];
...
}
The same again with one more dimension level (probably the most intutive solution):
However, essentially, the correct way (completely preserving types) would be
int c[10][10];
void getC(int (**p)[10][10]) // pointer to pointer to array of 10x10 ints
{
*p = &c; // &c can seamlessly change into a pointer to 10x10 ints
}
int main()
{
int (*a)[10][10]; // pointer to array(s) of 10x10 ints
int q;
getC(&a); // pass adress of pointer to 10x10 ints
q= (*a)[9][9]; // need *a in brackets to derference the pointer (operator precedence)
...
}
Can someone please tell me what's wrong with the following code? I'm getting EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS
I declare a global array of 7 pointers, each points to an int array, of different sizes.
int **pt_all_arrays[7];
In my function A()
for (int i = 0; i < 7; ++i) {
int array_size = function_that_returns_array_size();
int *myarray = (int *)malloc(array_size * sizeof (int));
// DO WORK...
// Store the array in the big array
*(pt_all_arrays[i]) = myarray; <-----EXCEPTION
}
The exception is thrown on the last line.
I'm running on Mac, gcc -std=gnu99
You would want to declare as
int *pt_all_arrays[7];
And then assign as
pt_all_arrays[i] = myarray;
With int **pt_all_arrays[7]; you create array of pointer to pointer to int, which is not what you want.
And with *(pt_all_arrays[i]) = myarray; you are trying to change to address of array which is not valid.
Example
int array[7];
int *pi;
array = pi; //this is not valid.
the definition of
int **pt_all_arrays[7];
should be
int *pt_all_arrays[7];
In the last line , you try to write to the memory location pointed by pt_all_arrays[i]. Since pt_all_arrays[i] hasn't been initialized, this might point anywhere. In your case, it points to an invalid memory address.
int **pt_all_arrays[7];
This actaully declaires an array of 7 pointers to pointers to ints. (pointers to int arrays). So if you want to store arrays you just need:
int *pt_all_arrays[7];
When you access the array:
pt_all_arrays[i]
This is actually saying the same as:
*(pt_all_arrays + i)
So you don't want to add the additional * in to it, simply:
pt_all_arrays[i] = myarray;
Will do.
How do you pass an array to a function where that function can edit it's contents?
like when doing
function(int *x)
{*x = 10;}
main()
{int x;
function(&x);}
how could i do the same using a character array?
whenever I do
function(char *array[], int *num)
{ int x = *num;
*array[x] = 'A'; }
main()
{ char this[5] = "00000"; //not a string
int x = 3;
function(&this, &x); }
DEV C++ says
[Warning] passing arg 1 of `function' from incompatible pointer type
obviously I did something wrong, so please tell me how to fix that. Thanks :D
You should write:
void function(char array[], int *num)
{
int x = *num;
array[x] = 'A';
}
void main()
{
char my_array[5] = "00000";
int x = 3;
function(my_array, &x);
}
Notation char *array[] is an array of pointers that you do not need here.
When you pass an array somewhere, you should not take its address. Arrays are adjusted to pointers by default.
EDIT:
Function prototypes:
void function(char array[], int *num);
void function(char *array, int *num);
are absolutely identical. There is no even minor difference between them.
Since arrays can only be passed by address, you don't really want a char * array here, just a char array:
rettype function(char *array, int *num)
{
array[*num] = 'A';
}
int main()
{
char arr[] = "1234567890";
int i = 2;
function(arr, &i);
}
In C, array names "devolve" to a pointer to the head of the array, by passing "&array", you're passing a pointer to a pointer to the head of the array, thus the warning.
char array[512];
myfunc(array, foo);
is the proper way to do what you want.
Actually you have taken one dimension array. So you can define function in two ways...
(i)
function(char array[], int *num)
{ int x = *num;
*array[x] = 'A'; }
main()
{ char this[5] = "00000"; //not a string
int x = 3;
function(this, &x); }
and
(ii)
function(char *array, int *num)
{ int x = *num;
*array[x] = 'A'; }
main()
{ char this[5] = "00000"; //not a string
int x = 3;
function(this, &x); }
But in your function definition, you wrote *array[] as argument which means the array is two dimensional array. So you should declare array as two dimensional array.
function(char *array[], int *num)
{ int x = *num;
//implement your code }
main()
{ char this[5][10];
// you can initialize this array.
int x = 3;
function(this, &x); }
I think it will be helpful to you.
Okay, the first thing to remember is that there's no such thing as a pointer "to an array" although you'll hear that said fairly often. It's sloppy.
(As pointed out below, the terminology "pointer to an array" does strictly have a meaning -- but I maintain that you've been confused by it. What really happens is that every pointer contains an address. Depending on the declaration, the compiler can identify if it's being used correctly in context, and that's what your error message is really telling you: what you declared in the function is a pointer to an array of chars, which is to say the same thing as a char **, instead of a char *, which is what you're passing. But char *, or char **, or char ******, the important point is that you're making it too complex -- you already have the address you need identified by the array name.)
Pointers is pointers, they're addresses.
An array in C is simply an allocated chunk of memory, and it's name represents the address of the first element. So
char a[42];
is a block of memory 42 char's long, and a is its address.
You could rewrite your second function as
void foo(char* a, int num){ // (3)
// notice that you don't need the word function and
// for lots of reasons I wouldn't use it as a function name.
a[num] = 'A'; // (4)
}
int main(){
// Sadly "00000" IS a string no matter what your comment
// says. Use an array initializer instead.
char arry[5] = {'0','0','0','0','0' } ; // (1)
foo(arry,3); // (2)
}
This does what I believe your code means to do. Note that
(1) Since "00000" really is a string, it's actually creating an array 6 elements long which could have been initialized with the array initializer
{'0','0','0','0','0', 0 }
(2) The array (which I named 'arry' instead of 'this' since 'this' is often a keyword in C-like languages, why risk confusion?) is already an address (but not a pointer. It can be on the right-hand side of an assignment to a pointer, but not on the left hand side.)
So when I call
foo(arry,3);
I'm calling foo with the address of the first element of arry, and the number 3 (you don't need to declare a variable for that.)
Now, I could have also written it as
foo(&arry[0],3);
You would read that as "find the 0-th element of arry, take its address." It is an identity in C that for any array
char c[len];
the expression c and &c[0] refer to the same address.
(3) that could also be defined as foo(char arry[], int num). Those are equivalent.
(4) and when you refer to a[num] you're referring directly to the num-th element of the memory pointed to by a, which is at the address of the start of the array arry. You don't need all that dereferencing.
Don't be disturbed that this is a little hard to follow -- it's tough for everyone when they start C.
Firstly dont use this as a variable name, its a C++ keyword. Sorry didnt realise it was a C question.
main()
{
char foo[5] = "00000"; //not a string
int x = 3;
function(foo, &x);
}
You dont take the memory address of foo. foo when used in a pointer-accepting context degrades into a pointer to the first element. *foo is the same as foo[0] which is the same as *(foo + 0)
like wise foo[3] is the same as *(foo + 3) (the compiler takes care of multiplying the element size).