0

c++

p is pointing to specific place

int * p

When I try p=p[1] it says can't convert int to int (using devcpp).

While p=&p[1] works fine

Why do I need to do the second method? p[1] is an address. So the first method should work? Can you explain me about this error?

Ro Yo Mi
  • 14,790
  • 5
  • 35
  • 43
John Smith
  • 13
  • 1
  • 8
    `p[1]` is not an address, it's an element. – chris Jul 11 '13 at 23:01
  • Have you created p as `int *` or `int`? – unxnut Jul 11 '13 at 23:02
  • @chris we don't know the type of `p`. If `p` is an array of pointers, then `p[1]` is a pointer value, and a pointer value is an address. But of course from the error, it seems `p` is not an array of pointers. – ouah Jul 11 '13 at 23:04
  • @ouah, There was that and there was the fact that it said `p` is pointing to something, though with all the confusion surrounding arrays vs pointers, that doesn't hold much ground. – chris Jul 11 '13 at 23:06
  • @chris your statement is written like if an array element could not be an address. – ouah Jul 11 '13 at 23:08
  • @ouah, Fair enough, I was directly addressing the OP's `p` with my assumptions of what it was, but that by itself looks much different, and as you say, could evaluate to an address. – chris Jul 11 '13 at 23:09
  • 1
    @John Smith: What made you believe that `p[1]` is an address? – AnT stands with Russia Jul 11 '13 at 23:10
  • @ouah Of course we know the type of 'p'. It's a pointer to int. What are you talking about? p[1] is therefore an int, and therefore not a pointer. – user207421 Jul 11 '13 at 23:13
  • 1
    @EJP, The code block wasn't there before. – chris Jul 11 '13 at 23:14
  • Hmm, no evidence of editing, musta been pretty quick. Anyway the comment is obsolete. – user207421 Jul 11 '13 at 23:15
  • `p[1]` is an `int` object, and it may or may not exist depending on the value of `p`, (i.e., what `p` points to, if anything). Presumably the error message is not "cant convert int to int", but "can't convert int to int*". We can tell you why the compiler doesn't accept `p=p[1]`, but we can't guess what it *should* be without knowing what you're trying to accomplish. – Keith Thompson Jul 11 '13 at 23:42

3 Answers3

1

p[1] is the same as *(p + 1).

You want the address of this element, which is simply (p + 1). C++ also allows &p[1], as you noticed.

chrisaycock
  • 36,470
  • 14
  • 88
  • 125
  • To be pedantic, p[i] is actually *(p + i * sizeof(*p)). So for 32-bit integers, *(p + 4). – C0deH4cker Jul 13 '13 at 12:01
  • 1
    @C0deH4cker No, it's `*(p + i)`. The compiler performs sizing automatically in pointer arithmetic, whether you want it to or not. Give it a try. – chrisaycock Jul 13 '13 at 14:22
0

p[1] is equivalent to *(p + 1) so it's a value, not an address. p = p + 1 or just p++ would be what you want.

Kninnug
  • 7,992
  • 1
  • 30
  • 42
  • but when i do int * p; cout<

    – John Smith Jul 11 '13 at 23:04
  • 3
    @JohnSmith, That's undefined behaviour. You're trying to access memory that you haven't allocated. – chris Jul 11 '13 at 23:05
  • 1
    @JohnSmith It's not printing an address; it's printing whatever garbage is currently in that memory location, which happens to look like an address. – chrisaycock Jul 11 '13 at 23:06
  • what is that garbage? its the data stored there? why we not using *(p+1) instead of p[1] – John Smith Jul 11 '13 at 23:08
  • @JohnSmith it's whatever is left in memory at that location, it can be anything. But you're not supposed to read it as you didn't allocate it. And remember that while `int * p;` gives you a pointer, it doesn't allocate the memory for it to point to. So at that point `*p;` isn't defined either. – Kninnug Jul 11 '13 at 23:09
  • @JohnSmith, We use the latter because it's shorter and easier to read. – chris Jul 11 '13 at 23:10
  • thanks guys. can you explain to me why when trying to int * p; int n[20]; n[0]=5; what should i do to make the pointer pointing to the address of first element ?? p=n? or p=&n? why when pointer pointing to pointer that points to int i get the value when doing p=n i get the address or value cuz n is a pointer to first element – – John Smith Jul 11 '13 at 23:39
  • i dont get it. p is pointing to specific memory address, why cout<

    – John Smith Jul 11 '13 at 23:54
  • As long as you don't initialise `p` (`int * p = ...;`) it doesn't point to anything. So `cout << p;` and `cout << &p` printing the same thing is coincidence (or maybe some underlying mechanic to do with uninitialised pointers). Try `int i = 4; int * p = &i;` and then print the address and the value of `p`. – Kninnug Jul 11 '13 at 23:57
0

While p is anint*, p[1] is an element from that array, therefore p[1] is int.

You can do p = &p[1] in other ways, for instance, p = p + 1, or p++. Both will set p to the same final value.

Notice when doing such arithmetic operations with pointers, it will not not increment the address by 1, its incrementing it by 1 times the size of one element, so its really the same thing.

Havenard
  • 27,022
  • 5
  • 36
  • 62
  • but when i do int * p; cout<

    – John Smith Jul 11 '13 at 23:06
  • Okay, when you do `int* p`, you declared a pointer, but you never told it where this pointer is pointing to. Its an undefined variable, and its content will be whatever was in the Stack at that moment. What `p[1]` will print will be some stack garbage, probably some address, but you can't really tell. – Havenard Jul 11 '13 at 23:09
  • m not using array of pointers. why i need to use the reference operator in p=&p[1] if i do int n[20]; int * p; p=n; why i dont do p=&n?? what is the garbage that stores in there? how i get it if im not using the dereference to get the value?? – John Smith Jul 11 '13 at 23:13
  • Because `&n` is `int**`, a pointer to a pointer of int, and `p` is `int*`, a pointer to int. And if this pointer is to an array or just an element it will only depend on how you use it, the synthax is the same. – Havenard Jul 11 '13 at 23:15
  • 1
    @Havenard, Wrong, `&n` is a `int (*)[20]`. – chris Jul 11 '13 at 23:16
  • 1
    @Havenard, Then why doesn't this compile? http://coliru.stacked-crooked.com/view?id=6905c51b81201d792d3ec6555081d87c-3b440a87a52fe2ae7c853c82f4c5144f – chris Jul 11 '13 at 23:17
  • 2
    @Havenard No, `int (*)[20]` is not the same as `int **`, because arrays are not pointers, and as a consequence, pointers to arrays are not double pointers ([link](http://c-faq.com/aryptr/aryptr2.html)). –  Jul 11 '13 at 23:25
  • Technically they are. There is no primary type that contains multiple elements. This type conversion limitation is just a compiler thing. – Havenard Jul 11 '13 at 23:28
  • thanks guys. can you explain to me why when trying to int * p; int n[20]; n[0]=5; what should i do to make the pointer pointing to the address of first element ?? p=n? or p=&n? why when pointer pointing to pointer that points to int i get the value when doing p=n i get the address or value cuz n is a pointer to first element – John Smith Jul 11 '13 at 23:32
  • @Havenard No, they aren't. Ever tried `int a[10]; int *b = a; printf("%zu %zu", sizeof(a), sizeof(b))`? If you haven't, [do so now.](http://ideone.com/If6isH) And read the article I provided a link to in my previous comment. They are conceptually very different. (And asserting that they are the same always indicates the abscence of solid C knowledge and arising out of the lack of understanding between the two data structure.) –  Jul 11 '13 at 23:36
  • 3
    @Havenard: You are badly mistaken. Arrays are not pointers, and pointers are not arrays. (An expressions of array type is *converted* to a pointer value in most, but not all, contexts.) Read section 6 of the [comp.lang.c FAQ](http://www.c-faq.com/); it explains this much better than I can do in a comment. – Keith Thompson Jul 11 '13 at 23:39
  • Okay guys, I've done enough reverse engineering to know what I'm saying, but if you are addicted to the compiler's abstractions carry on, it doesn't really matter. – Havenard Jul 11 '13 at 23:40
  • 2
    @Havenard Assembly isn't C, C is not assembly, and there's a very good reason for that. (I've done reverse engineering too, and I understand that you are trying to apply low-level ideas to a high-level language, but that's just not right. In C, we have types and we don't deal with untyped raw blocks of memory. And types matter. And the compiler will frown upon you if you don't respect the type system - because code that doesn't respect it makes no sense.) –  Jul 11 '13 at 23:41
  • 2
    @Havenard: Apparently you were seriously confused during your reverse-engineering exploits. The fact that arrays are not pointers is not a "compiler abstraction". It is a hard practical fact. No real-life C or C++ compiler implements regular arrays as pointers. It is simply *impossible*, for which reason you will never see an array implemented as a pointer in real-life machine code compiled from C or C++ sources. The only exception from this rule are C99 variable length arrays, which is exactly what limits their usability to certain specific contexts. – AnT stands with Russia Jul 12 '13 at 01:54