Uh, why are you doing this at all? Since you are passing in a pointer, you are going to be modifying the input array - there is nothing to return.

Also you really should be passing in the size of the array. Or, better yet, don't use an array at all and instead use one of the std container classes like vector.
...so X[Y] just adds the two together and dereferences?? That's...(NUTS_flag & SOMEHOW_SMART_flag)!!!

(WARNING: Technical ramble follows; especially in the sense of "technicality"...)
I'd bet it's true that "int array[]" does declare an actual block of memory (which can then not be changed as a whole, since it's declared directly than that being a pointer to some block), and then using "array" by itself just gives it's address ...
HOWEVER, I think that the conceptual implication is that it IS a pointer: You use it in all the same ways with all the same syntax, and even the variable name by itself gives you the address of the array (or rather, the first element of it) that it is "pointing to". This concept must hold true in order for you to be able to assign this kind of array to a pointer (e.g. to an "int*" rather than an "int[]*", if such a thing existed). The only difference is that you cannot reassign it. Of course, the actuality (which is important to understand) is that the compiler stores it statically, but then adds in automatic addressing and stuff so that it behaves as if it it were a pointer to an underlying array. (For this reason, I am surprised that "int array[]" is not just MADE constant elsewhere just to be uniform with what that declaration is "supposed" to mean [as I explained it, anyway; e.g. maintaining the conceptual implications of being const rather than the actuality that it has to be a pointer when it's a parameter for it to even work uniformly] ... though I suppose it also doesn't surprise me, since C++ tends to exploit actualities).

...Anyway............... that all aside, if we treat "int* x" and "int y[]" both as int-pointers (or int-array pointers), then it makes sense (in the easy-compiler-coding sense) to just have "X[Y]" mean "*(X+Y)" since "x[i]" means "*(x+i)" and "y[i]" means "*(y+i)"; which in turn makes the initially bizarre "2[x]" syntax suddenly make perfect sense! ... AHHH!!!!!!

On a side note, these ties between arrays and deferencing have brought me to consider coming up with my own syntax and semantics for such:
- A minimalist approach would abolish "[]" and resort to things like *(base+index)" ... you can do all the same stuff that way anyway Smile
- If "X[Y]" and "Y[X]" are identical to "*(X+Y)", then perhaps both could be replaced with a syntax like "[X+Y]" (which is just my minimalist approach all over again, but using "[X]" instead of "*X"). A point in favor of this is that it always makes it clear what order things happen in, versus "*a[i]" (e.g. "[[a+i]]" or "[[a]+i]").
shkaboinka wrote:
...so X[Y] just adds the two together and dereferences?? That's...(NUTS_flag & SOMEHOW_SMART_flag)!!!

(WARNING: Technical ramble follows; especially in the sense of "technicality"...)

Yep, that's the gist of it. Also, it's legal only to add a pointer and an integer. You cannot add two pointers; that doesn't make sense anyway.

I just thought of this connection to 68k asm: some assemblers (eg, the GNU assembler) accept a couple of different syntax forms for the address register with offset. The following instructions are equivalent (they produce the same machine code):

Code:
    move #7,4(%a0)
    move #7,(4,%a0)

Both instructions move the value 7 to the address pointed to by %a0+4 (%a0 is an address register, so it holds a pointer). These instructions might have been produced with this C code:

Code:
p[4] = 7;
*(p+4) = 7;

(I think 68k asm is pretty nice since C expressions can often be translated into few instructions.)
shkaboinka wrote:
I'd bet it's true that "int array[]" does declare an actual block of memory (which can then not be changed as a whole, since it's declared directly than that being a pointer to some block), and then using "array" by itself just gives it's address ...


It doesn't. "int array[<size>]" declares a block of memory on the stack. "int array[]" doesn't declare a block of memory, it is conceptual and practically identical to "int *array"

If you use [] a lot you will likely run into weird compiler errors that don't make much sense, so I recommend using just pointers for any array allocated on the heap, and using [] for anything on the stack.

Quote:
rather than an "int[]*", if such a thing existed).


Have you never typed "int main(int argc, char* argv[])" ? Razz
Kllrnohj wrote:
shkaboinka wrote:
I'd bet it's true that "int array[]" does declare an actual block of memory...


It doesn't. "int array[<size>]" declares a block of memory on the stack. "int array[]" doesn't declare a block of memory, it is conceptual and practically identical to "int *array"

If you use [] a lot you will likely run into weird compiler errors that don't make much sense, so I recommend using just pointers for any array allocated on the heap, and using [] for anything on the stack.
My point was that it is like a pointer and meant to be conceptualized that way; but perhaps it was stored as (not a pointer) as a compiler/language optimization ... But the that's very helpful to know that it actually uses the stack! That means you have direct control whether to use the heap ("new") or the stack; which is pretty awesome! Smile

Kllrnohj wrote:
Have you never typed "int main(int argc, char* argv[])" ? Razz
No, but I've seen "char** argv", which I would say is the same were it not for the difference of allocation as you pointed out.
shkaboinka wrote:
Kllrnohj wrote:
shkaboinka wrote:
I'd bet it's true that "int array[]" does declare an actual block of memory...


It doesn't. "int array[<size>]" declares a block of memory on the stack. "int array[]" doesn't declare a block of memory, it is conceptual and practically identical to "int *array"

If you use [] a lot you will likely run into weird compiler errors that don't make much sense, so I recommend using just pointers for any array allocated on the heap, and using [] for anything on the stack.
My point was that it is like a pointer and meant to be conceptualized that way; but perhaps it was stored as (not a pointer) as a compiler/language optimization ... But the that's very helpful to know that it actually uses the stack! That means you have direct control whether to use the heap ("new") or the stack; which is pretty awesome! Smile

Kllrnohj wrote:
Have you never typed "int main(int argc, char* argv[])" ? Razz
No, but I've seen "char** argv", which I would say is the same were it not for the difference of allocation as you pointed out.

IIRC, passing arguments to a function is done over the stack. In fact, I'm almost sure of that. If I recall, there are 3 basic reasons the stack is used.
1. Return values
2. Passing in parameters
3. Local variables

And usually, the heap is whenever you call "new" on something.
char *argv[] and char **argv are identical when found inside a function's parameter list. They both mean argv is a pointer to a pointer to a char. Neither one suggests that the char is on the stack or on the heap*.

The pointer itself might be pushed on the stack, depending on the compiler's/platform's calling convention. Some combinations of compilers and platforms even pass the first few arguments in registers instead of on the stack. However, these details are irrelevant unless you start mixing other languages (eg, assembly) in the same program.

On the other hand, a local variable array (eg, int foo[2]) is stored on the stack, but a local variable pointer (eg, int *foo) may also be stored on the stack, but that pointer can point to any int object, whether it's on the stack or on the heap. If you call malloc or new to allocate space for an array, then it'll be stored in the heap. You could alternatively point foo at a local variable, in which case it would point to something on the stack:
Code:
  int x;
  int *y = &x; // y points to an object on the stack
  int *z = malloc(sizeof(int)); // z points to an object on the heap


Oh, and graphmastur: the stack is also used for saving registers (both caller- and callee-saved registers).


* I believe in Linux and other *nix systems, a process's argument list is pushed onto the stack by the kernel before the process starts, but C doesn't really care where it is (the C runtime code has to care, of course).
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 2 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement