This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C: How come an array's address is equal to its value?
I recently found code in my project that calls memcpy with the address of array name
int a[10];
memcpy(&a, &b ,sizeof(a));
Surprisingly (to me) it seems to work.
Should I change it to memcpy(a,b,sizeof(a)); ?
Is it allowed by the C++ spec?
Can anyone point me to resource about this behavior? Are there any pitfalls?
I also checked
assert((void*)&a == (void*)a);
and &a indeed is the same as a (besides it's type).
I verified this behavior in VS2005, VS2008 and VS2010.
&a is the address of the array; a can be implicitly converted to the address of the first element. Both have the same address, and so both will give the same value when converted to void*.
Are there any pitfalls?
memcpy is not typesafe, so it's quite easy to write code that compiles but behaves badly; for example, if a were a pointer rather than an array, then sizeof a would compile but give the wrong value. C++'s typesafe templates can protect against that:
std::copy(b, std::end(b), a); // will only compile if `b` has a known end.
The name of an array evaluates to the address of the beginning of the array, so the two have identical meaning. See How come an array's address is equal to its value in C? (it's a C question but the same holds for C++).
Like you say, it doesn't matter.
When passed as a parameter, the name of the array will "decay" into a pointer to its first element.
Yes, the address of an array is the same as the address of its first element.
So there's no need to change the memcpy call. Unless you're afraid that the definition of the array might change to a pointer later (like int* a = new int[10];).
Of course, if you're going to make changes to the program anyway, it might be best to dispense with the whole memcpy and use real C++ instead.
Related
I've been told that the following is bad code because z_strings is already a char array. However I don't really know much C++ so I don't really know what the usage is doing or why it would be wrong. Can somebody offer an explanation?
Declaration: char z_strings[3];
Usage: MyFunction(myints, (char**)&z_strings, another_int_arg);
Definition of MyFunction: void MyFunction(int* my_ints, char** z_strings, int another_int_arg)
For context, this is a coworker's "code review" code which is intentionally broken; he was using it to ask interview candidates to fix the bad code. However this coworker has actually left the company and the only notes say that it's a bad cast, and I'm trying to figure out some more details about why because I'm curious.
I removed context I thought was irrelevant, but for the full context MyFunction is actually GetPowers(p_int, (char**)&z_strings, 3); p_int will be an array like [2,3,4] and z_strings will be populated with values like ['Hundreds','Thousands','Ten Thousands'], in other words this function translates numerical powers into English equivalents.
Unlike the widespread and erroneously taught belief, arrays are not pointers. They may decay into pointers in most contexts, but the address-of operator is not one of those contexts.
If the type of z_strings is char[3], then the type of &z_strings is char (*)[3]. It is a pointer to an array of three characters. And a pointer to an array is not compatible with a pointer to a pointer.
That's what's wrong with your cast. As for how to fix it, with the little context you've shown, the obvious solution is to introduce an actual pointer:
char *p_z_strings = z_strings; //decay here
MyFunction(myints, &p_z_strings , another_int_arg); // no cast; exact match
With the added context you provided, the "obvious" solution is now rather glaringly incorrect. There's still a few details missing, but if we are working under the assumption that GetPowers will do the allocation for the new strings, we do not need additional variables:
char* z_strings[3]; // Now we have an array of pointers
GetPowers(p_int, z_strings, 3); // It decays into a pointer to a pointer
// GetPowers populates it
The cast is bad, because it shuts up the compiler, without fixing the code.
The real fix might be using the proper array, which could be (as the function argument type suggests) an array of pointers, e.g.
char *z_strings[3];
Now you can call the function without any cast at all:
MyFunction(myints, z_strings, another_int_arg);
In C and C++ an array 'decays' to a pointer when the identifier is used as an argument to a function that expects a pointer. This means that if you have a function that takes a char* (C and common C++ form of a string argument) then you can just pass it a char array and no casting is required.
In your example, you are casting to a char** which is a pointer to a pointer to a char. This suggests the function expects to change what a char* argument points to and this is not something that makes sense with an array argument. Without knowing more context here it's hard to give a more specific answer to your question though. It's also possible that a char** argument could be intended to be an array of strings (in which case you would expect an additional array size argument) but without seeing what MyFunction() is intended to do it's hard to say.
Memory addresses are often displayed in hex formate like 0x7ffff3a9ae94. Why we can't directly assign these values to pointers?
int *ptr=7ffff3a9ae94;
A "similar" behavior was shown when i tried this.(This might be a separate question itself)
int i=0;
*ptr=&i;
&i=ptr;
Both cases show syntax errors on g++ 4.7.2 which, i assume means its a language restriction.
Why this restriction is implemented in C++?
Or is this some kind of OS limitation?
Note: This question have similar title but it doesn't provide me answer to my question.
there is no such rule , this :
int *ptr=(int*)0x7ffff3a9ae94;
compiles fine.
although it's a bad thing to to.
intresting fact : the idea that you can convert pointer to integer and vice versa is one of the biggest blocks when talking about garbage collector in C++ in general. you can (althoug it's stupid) to serialize the memory address in some external buffer, then re-assign it to some pointer. the GC may think it can delete the variable because nowone else points at it - while the pointer is still "valid" and will be dereference somewhere in the future
Is the name of a vector simply a pointer, just like a vanilla C array?
Thus, I could send the address to a single piece of non-vector data (a pointer, in other words) to a function argument that expects a vector since a vector is also a pointer.
For example, a function that is declared as this:
void RenderingEngine::Render(const vector<Visual>& visuals) const{
Could be called like this:
Visual visual; // is NOT a vector
//do stuff with visual
m_renderingEngine->Render(&visual);
Makes sense and is valid, legal C++?
This example code is from an O'Reilly C++ book, so I guess it is an error in the book.
Is the name of a vector simply a pointer, just like a vanilla C array?
No. It's a fully-formed class.*
* What's more, a vanilla C array is not a pointer either (it just get turns into one in most situations).
No. That doesn't make sense. There is no implicit conversion from T* to std::vector<T>.
But in C++11, you can do something which is very close1 to what you're doing. You could create the vector on the fly while passing the argument as:
m_renderingEngine->Render( {visual} ); //note the curly braces!
With that you create a vector object out of the expression {visual} which then gets passed to the function.
1. very close in the sense that you just have to type one more character to make your code work. Instead of typying &, just type {, and one more } at the end. That is it. Life is so easy with C++11.
No, it isn't, which is rather fortunate because the behaviour of C arrays is abominable. If you find yourself looking for it, I would suggest instead looking for some new learning material w.r.t. C++.
The other answers are correct, but I'd like to add that it works the other way around:
void RenderingEngine::Render(Visual *visuals, size_t n_visuals);
Can be called like this:
vector<Visual> visuals;
m_renderingEngine->Render(&visuals[0], visuals.size());
You just take the address of the first element and pass it as if it was an array. This works because the elements of a vector are laid out sequentially in memory. (As pointed out in the comments, shouldn't use this in new code, of course. It's safer and easier to define you method to take a vector. However, if you already have a legacy function that takes a pointer, this allows you to use vectors in your own code.)
The reason it works this way around, but not the way in your question (pass a pointer, to a function that takes a vector), is that in your case it can't determine the size of the array at runtime. But it has to know the size to construct the vector:
// (wrong code)
// Passing one element:
Visual visual;
m_renderingEngine->Render(&visual);
// Passing two elements, how does Render know that
// there are two elements at that address?
Visual[2] visuals;
m_renderingEngine->Render(&visuals[0]);
As Nawaz pointed out, you can do something similar in C++11:
Visual visual;
m_renderingEngine->Render( {visual} ); // C++11
You can also put more elements in the {}. This only works because the compiler can tell at compile-time how many elements there will be. It's just syntactic sugar for:
vector<Visual> myVec = {visual}; // C++11
m_renderingEngine->Render(myVec);
which in turn works like the classic:
vector<Visual> myVec;
myVec.push_back(visual);
m_renderingEngine->Render(myVec);
(although the C++11 version might be slightly optimized, I don't know for sure).
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why does simple C code receive segmentation fault?
Why code snippet 2 doesn't behave like snippet 1?
//Code snippet 1
char pstr[] = "helloworld";
char *p = pstr;
p[2] = 'd';
//Code snippet 2
char *p = "helloworld";
p[2] = 'd'; //error: access violation
P.S Forgive my ignorance.
The first snippet creates an array of char and initializes its contents to "helloworld". Then you change its third element.
The second one simply creates a pointer to char that points to a string literal. Then you attempt to change the third character of that literal. String literals are not writable in code produced by many modern compilers.
EDIT:
GCC used to have an -fwritable-strings option that enabled string literals to be writable, since there is legacy code around that depends on this behaviour. That option was removed in the GCC 4.0 release series.
"helloworld" is an array of const char. There's a hole in the type system which allows you to point to it with a char*, because a lot of code exists which uses a char * to point to readonly data and this is safe.
But const_cast rules apply, you can't actually write to the const data even if you make a non-const pointer to it.
It would help if you could tell us in what way they're behaving differently.
But as a guess, I think your problem is that the second form has 'p' pointing to a string in read-only memory. Attempts to write through the pointer 'p' would result in a program failure.
I can tell you that the Gnu c++ compiler will warn you about this.
I'm guessing when you say "doesn't behave like" you mean one throws an illegal access exception (or something similar) while the other gives a compile time warning or error?
The answer is that in the first case, you're creating a pointer to your own memory, and copying the c9ontents into it. At that point the compiler forgets it used to be a pointer to static memory; the run time system, however, doesn't forget.
In the other case, the compiler "knows" p is a pointer to static memory, and so has the chance to say "whoa, dude, can't do that".
But this is a bit of a guess without knowing exactly what it does differently. it's also going to be compiler and implementation dependent.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How do pointer to pointers work in C?
Hello,
Altough I think I passed the newbie phase in programming I still have some questions that somehow I can't find them explained. Yes, there are plenty of "how to"s overthere but almost always nobody explains why and/or when one technique is useful.
In my case I have discovered that in some cases a pointer to a pointer is used in C++. Is not a pointer to an object enough? Which are the benefits? Where or when should be used a pointer to a pointer? I feel little bit desorientated in this matter.
I hope time experienced expert could respond to this concerns that hopefully is shared by other no so experienced programers. ;-)
Thank you everyone.
Julen.
Well, it is somehow hard to answer to such a general question.
First answer of a C++ programmer will certainly be : Do not use pointers in C++ ! As you have a lot of safer ways to handle problems than pointers, one of your goal will be to avoid them in the first place :)
So pointers to pointers are seldom used in C++. They are mainly used in C. First, because in C, strings are "char*" so when you need a "pointer to a C string" you end with a "char**". Second, as you do not have references in C, when you need to have a function that modify a pointer or that give a pointer as an output value, you need to give a pointer to a pointer parameter. You typically find that in functions that allocate memory, as they give you a pointer to the allocated memory.
If you go the C++ way, try to avoid pointers, you usually have better ways.
my2c
In C, an argument is passed to a function that changes it, through a pointer. You will see the same with C++ for old or legacy code (int main(int argc, char** argv)) , for code that will be accessed from C (COM / XPCOM) or with code that was written by someone used to C (or the C style).
From a "purely C++" standpoint, using pointer to pointer is in most situations a sign of poor coding style, as most situations that require a ** construct can (and should) be refactored to use safer alternatives (like std:: containers, or *& parameters).
I can think of two use cases.
One is arrays as inherited from C. Arrays automatically decay to pointers to their first elements in many cases. If you happen to have an array of pointers, you get a pointer to a pointer for that.
(Something similar can happen when you have a std::vector of pointers, BTW: A pointer is a perfect random access iterator and I have indeed seen std lib implementations using pointers for std::vector<>::iterator. For a std::vector of pointers, v.begin() would return a pointer to a pointer.)
The other is for function arguments. For function arguments, taking something per pointer indicates that callers might call the function even if they don't have an object to pass in; they can pass in NULL then. (Otherwise why take a pointer instead of a reference? See here for more details on this).
Taking a non-const reference to a pointer would indicate that the called function might assign a new address to that pointer.
So taking a pointer to a pointer would indicate that the function might assign a new address to a pointer, if the caller passes in a pointer to it, but is callable with NULL as well.
For example:
void f(int** ppi);
void g(int i);
void h()
{
f(NULL); // call `f()` only for its side-effects
int* pi = NULL;
f(&pi); // call `f()` and get some object in *pi
if(pi)
g(*pi); // use result
}
Where or when should be used a pointer to a pointer?
In a function that optionally may return pointer to caller, if the caller requests that. Frequently used by system APIs, some COM objects, etc.
int f(void** p = 0){
//.......
}
If caller provides p, then function passes pointer through p. If caller doesn't provide p, then no pointer is returned. May be useful for debugging purposes in certain situations.
Which are the benefits?
The question is too broad. Look, it is a VERY simple technique without some kind of mysterious benefits. You use it when you have to. That's all. There is no hidden meaning and no secret advantages of this concept - it is equivalent to asking "what are benefits of using letter \"e\" in english language".
Pointers to pointers have most relevance in C. Seldomly, you need them in C++. There you can work with containers from the std lib or with references.
There are two popular use cases in C though:
An array of pointers, most prominently used as argv to main(): the pointer gives the address to the array of argument strings (type char*). In C, the [] operators work on pointers to anything as pointers to anything are seen as an equivalent to arrays.
A function argument denoting a place where to store the address of something. Use case: In C, the return value is often used for error handling or state information. Arguments are used for carrying the payload. One example: A function "returns" an address to newly allocated memory, but using an argument. You give the function a pointer to the pointer that should afterwards point to the data. The function overwrites that space and for that, it needs a pointer to a pointer.
You only use them when employing manual memory management, something that's rare as hell in C++, therefore they're pretty useless. Even regular pointers are of questionable value in the majority of scenarios.
There're actually two use cases.
First, is when you call a function that has to return more than one value, some of which, are pointers. Then, you would provide her with an address of a pointer, so it could fill in the pointed pointer:
int *p1 = 0, *p2 = 0, *p3 = 0;
multi_malloc(&p1, &p2, &p3); // Allocates three pointers
Second is when you want to do sparse 2d arrays:
int main(int argc, char **argv)
This is a pointer to pointer. argv[i] is a pointer to char. This way, argv[i][j] is a char j in row i.
You will be happy to hear that there're nearly zero uses for pointer to pointer to pointer. int ***p; is almost never useful.