pointer to array c++ - c++

My understanding about assigning an array to a pointer is that the pointer is pointing at the first index of the array, so when printout the pointer, it should print out the address of the first index of the array, but how come in this case the cout printed out the value of the whole array? even though I explicitly indicated that I wanted the address of the first index
char foo[] = {'A','B','C','\0'};
char* p = foo;
char* q = &(foo[0]);
cout <<"from p: " << p << endl;
cout << "from q: " << q << " " << &(foo[0]) << endl;
//output
from p: ABC
from q: ABC ABC
the second question is that I see the difference between those two lines is that one is an array of pointer to char, the other is a pointer to a char array, is that correct? is the parenthesis necessary?
char* bar1[4];
char (*bar2)[4] = &foo;
cout << "address of foo is " << bar2 << endl;
//output
address of foo is 0x7fff192f88b0
The address of the foo array should be the same as the address of A, right? How do I printout the address of A? since I failed to do so. Thank you very much

<< has a dedicated overload for const char *, because that's what a C-style string is. Try this:
cout << static_cast<const void *>(bar2) << endl;

Related

c++ segfault and pointers confusion (I have the feeling I'm missing something terribly obvious)

I'm a python programmer new to C++. Currently getting a segfault when trying to play around with pointers. Can someone explain this behavior? I suspect there's something significant about cout that I'm not understanding.
#include<iostream>
using namespace std;
int main() {
int var; // declaration
cout << "var declared" << endl;
cout << "var : " << var << endl;
cout << "&var : " << &var << endl;
var = 10; // initialization
cout << "\nvar initialized" << endl;
cout << "var : " << var << endl;
cout << "&var : " << &var << endl;
int* ptr; // declaration
cout << "\nptr declared" << endl;
cout << "ptr : " << ptr << endl;
cout << "*ptr : " << *ptr << endl;
cout << "&ptr : " << &ptr << endl;
ptr = &var; // initialization
cout << "\nptr initialized : " << endl;
cout << "ptr : " << ptr << endl;
cout << "*ptr : " << *ptr << endl;
cout << "&ptr : " << &ptr << endl;
return 0;
}
using this compiler command
g++ --std=c++14 main.cpp -o main_exec;
This code produces the following output
var declared
var : 0
&var : 0x7fff55724478
var initialized
var : 10
&var : 0x7fff55724478
ptr declared
ptr : 0x0
[1] 82727 segmentation fault ./main_exec
This code obviously compiles but produces a segfault at runtime.
Things I've tried
I've tried combinations of commenting out the lines that include *ptr and the lines that include &ptr, short story is some combinations produce no segfault. It seems that I can use *ptr 1 time and not in combination with &ptr
You declared a pointer to an integer, but not initialized or assigned it with any pointer (i.e. to memory address of an integer variable).
int* ptr; // declaration
The line above says, ptr is a pointer (that would point to memory address of an integer variable). In your case it just says it is a pointer, what it does point is not defined.
When you hit this line,
cout << "*ptr : " << *ptr << endl;
Here *ptr means, get the value at address (the address that actually would store the value) and is being pointed by ptr. However ptr points to nothing. So you're trying to access memory in a way that is not permitted which leads to the segmentation fault.
Just remember that pointers are variable that as their values store memory address of another variable.
int *ptr; // would store memory address of an integer type variable.
int a = 5; // would store an integer variable.
ptr = &a; // Here &a gets the address of variable a and stores in *ptr
cout<<*ptr // Here *ptr gets the value of variable whose memory address is pointed to by *ptr.
Edit
To answer the question if int * ptr = new int; is valid.
Yes it will reserve you a memory location and allows you to later store values on that location later, as shown in code below,
int* ptr = new int; // gets memory address and assigns to *ptr
*ptr = 5; // assigns value 5 to the memory being pointed by *ptr
cout<<*ptr; // output 5
However you're supposed to not do this unless you've a particular need.
Variables reserve you memory, and give you a friendly variable name of your choice.
Anything you create with new is not deleted automatically, as suggested in comment section.
Variables, in contrast to this, are deleted automatically when they get out of scope (block, function, loop, etc.)

Does char* have other functions than as a pointer in C++? [duplicate]

This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 3 years ago.
If char* is a pointer (I find its size is always 4 bytes), how do I find its value (the address in hexa or decimal)? I tried &(*p) for char *p. It simply returned the initial string. If it is always 4 bytes, how is it that it can be initialized to long strings but point to the first character? In other words where is the string stored?
Is char* a weird pointer used for purposes other than what a pointer is intended to be?
// an initial pointer (usually its size is 32bit or 64bit, depending on CPU/OS).
// it's value is currently NULL (not pointing anywhere),
// so we can't do very much with this right now.
char* p = nullptr;
// for the sake of sanity, check the value (should be zero)
// we have to convert to intptr_t, otherwise we'd get the string
// value being printed out.
std::cout << "p address = " << intptr_t(p) << std::endl << std::endl;
// lets allocate a few chars to play with
p = new char[10];
// copy in some text value
std::strcpy(p, "Hello");
// and now if we print the address, the text string,
// and the char we are pointing at
std::cout << "p address = " << intptr_t(p) << std::endl;
std::cout << "p string = " << p << std::endl;
std::cout << "p dereferenced = " << *p << std::endl << std::endl;
// for fun, lets increment the pointer by 1
++p;
// this should have made a couple of changes here
std::cout << "p address = " << intptr_t(p) << std::endl;
std::cout << "p string = " << p << std::endl;
std::cout << "p dereferenced = " << *p << std::endl << std::endl;
// decrement again (so we can delete the correct memory allocation!)
--p;
// now free the original allocation
delete [] p;
// if we print again, notice it still has the memory location?
std::cout << "p address = " << intptr_t(p) << std::endl;
// This would be bad to access (we've just deleted the memory)
// So as a precaution, set the pointer back to null
p = nullptr;
// should be back where we started
std::cout << "p address = " << intptr_t(p) << std::endl;

C++ - Does anyone have any tricks for analyzing pointer to pointer problems?

I've been given a set of different Pointer to Pointer exercises. Each dereferencing an array of pointers. It's definitely challenging and confusing when analyzing them without a compiler. Does anyone have any systematic tricks to solve them?
int main(void)
{
const char* s[] = { "AB", "XY", "EZ"};
const char** z = s;
z += 1;
cout << "The value of **z is: " << **z << endl;
cout << "The value of *z is: " << *z << endl;
cout << "The value of **(z-1) is: " << **(z-1)<< endl;
cout << "The value of *(z-1) is: " << *(z-1)<< endl;
cout << "The value of z[1][1] is: " << z[1][1]<< endl;
cout << "The value of *(*(z+1)+1) is: " << *(*(z+1)+1)<< endl;
return 0;
}
I have another puzzle here, which is definitely a little bit shorter.
int foo[] = {1, 4, 9};
int bar[] = {16, 26, 36, 49};
int main(void){
int *x[2];
x[0] = bar;
x[1] = foo;
*x[1] = (*x)[1];
//What changes?
}
I was able to get the correct results after a while, but I cannot consistently get the correct answers.
I'm looking for a trick similar to reading a function containing "const" right to left. I.e.
const char **x;
"x is a pointer to a char pointer that is constant."
ANSWERS BELOW:
-
-
-
The answers are:
**z is X, *z is XY, **(z-1) is A, *(z-1) is AB, z[1][1] is Z, * ( *(z+1)+1) is Z.
There are no tricks, it's just a matter of understanding the mechanics of each piece of the puzzle. Let's break it down.
z += 1;
z starts at s[0], so now it's s[1].
cout << "The value of **z is: " << **z << endl;
**z is the same as *s[1], which is the same as s[1][0]. Which is 'X'.
cout << "The value of *z is: " << *z << endl;
*z is the same as s[1], which is a char* pointer pointing to XY.
cout << "The value of **(z-1) is: " << **(z-1)<< endl;
**(z-1) is the same as *s[0]. Which is 'A'.
cout << "The value of *(z-1) is: " << *(z-1)<< endl;
By now the pattern should be obvious, this is s[0] which is a pointer to "AB".
cout << "The value of z[1][1] is: " << z[1][1]<< endl;
z[1] is the same as *(z+1); since z is already s+1, that means the expression is the same as *(s+2) or s[2]. Taking an additional subscript from that is indexing into the pointer at s[2], so s[2][1] is the second character of the string or 'Z'.
cout << "The value of *(*(z+1)+1) is: " << *(*(z+1)+1)<< endl;
Working our way from the inside parenthesis out, *(z+1) we've already determined is s[2]. Adding 1 to that pointer gets to the second character just as in the previous example, and dereferencing that pointer with * results in the character 'Z'.
So I don't know if this is the most efficient way of doing it, but the way I understand it is that [] and * are almost interchangeable for pointer to pointers. It's almost like a 2D array. It's just that [] has a higher precedence than *.
Therefore, looking at **z, we can analyze it as z[0][0]. For a more challenging example, we can analyze **(z-1) as z[-1][0]. Finally, the most challenging, *(*(z+1)+1) can be analyzed as z[+1][+1].

The number of elements in an array using pointers in C++

So while studying for my exams I was trying to do a practice problem for pointers.
In the following code I'm trying to display the number of elements before the first occurrence of 0.
There is only one part that i didn't understand please see the 6th last line.
#include <iostream>
using namespace std;
int main()
{
int A[10];
for (int i = 0; i < 10; i++){
cout << "Please enter number " << i + 1 << " in the array: ";
cin >> A[i];
}
int *Aptr = A;
while(*Aptr !=0){
cout << *Aptr << "";
Aptr++;
}
cout << "\nThere are " << (Aptr - A) //Here is what i don't understand.
<< " numbers before the first occurrence of 0." << endl;
system("pause");
return 0;
}
So why exactly is (Aptr - A) giving me the number of elements instead of a memory location, and why is this even doable since Aptr is a pointer and A is an array?
Can someone explain to me in detail?
When used in an expression, like Aptr - A, the name of an array A will be implicitly converted to a pointer (equal to &A[0]).
Then the compiler is faced with subtracting two pointers of the same type (both of type int * in your case). That is specified as giving a value of type std::ptrdiff_t, which is, in turn "a signed integral type able to represent the result of subtracting two pointers".
Pointer arithmetic, when subtracting two pointers of type int (i.e. two int *s) gives the number of ints between the two pointers (assuming they are in the same object, which is true in this case, since Aptr points at an element of the array A).
Practically, if Aptr is equal to &A[i], the subtraction Aptr - &A[0] gives a std::ptrdiff_t equal to i.
Note: there is another problem in your code, as since the first (for) loop reads 10 values, while the second while loop keeps incrementing Aptr until it points at an int with value 0. If the user enters any zero values, the second loop will stop when it finds the first (even if the user enters non-zero elements after that). If the user enters no values equal to 0, then the while loop has undefined behaviour, since Aptr will keep walking through memory past the end of A until it happens to find memory that compares (as an int) equal to 0.
First of all, name of array A is associated to address of (pointer at) the first item in the array.
So why exactly is (Aptr - A) giving me the number of elements?
Because according to rules address arithmetic subtraction operation (also +, and similar) is performed based on the data type.
I mean, that compiler operating with int* makes ++, --, addition, subtraction an integer, etc. adds addresses needed for shifting to next/previous item.
If you really want to see how many bytes are located between addresses, just convert addresses to int before making subtraction:
cout << endl << "Address difference is " << int(Aptr) - int(A) << endl;
You can try that with different data types as follows:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int A[5];
short B[5];
unsigned char C[5];
cout << "Array (data type) | Syze of array | Size of item | Item distanse | Bytes distance" << endl;
cout << "A (int) :" << setw(10)
<< sizeof(A) << setw(15)
<< sizeof(A[0]) << setw(15)
<< &A[4] - A << setw(15)
<< int(&A[4]) - int(A) << endl;
cout << "B (short) :" << setw(10)
<< sizeof(B) << setw(15)
<< sizeof(B[0]) << setw(15)
<< &B[4] - B << setw(15)
<< int(&B[4]) - int(B) << endl;
cout << "C (un.char) :" << setw(10)
<< sizeof(C) << setw(15)
<< sizeof(C[0]) << setw(15)
<< &C[4] - C << setw(15)
<< int(&C[4]) - int(C) << endl;
system("pause");
return 0;
}
UPDATE
To be better prepared for your exam, consider the following example with pointers:
#include <iostream>
using namespace std;
int main()
{
int A[5] = {0}; // all items now are 0
int * P = A + 2; // the same as P = &A[2];
*P = 33; // writing to item A[2];
cout << A[2] << endl; // just to check in usual way
cout << *(A + 2) << endl; // using A as a pointer
cout << *(2 + A) << endl; // almost the same to previous
cout << 2[A] << endl; // quite strange, but it works
cout << 0[P] << endl; // and this is the same
return 0;
}
You must understand that 0[P] means for compiler *(0 + P), as well as 2[A] means - *(2 + A), but you should not write in your program in such style (exceptions are only cases when you want to confuse a reader).
And one more important thing - difference between array and pointer - are shown in the following example:
int A[] = {1, 2, 3, 4, 5};
int *P = A;
cout << "A = " << A << endl;
cout << "P = " << P << endl;
cout << "size of A = " << sizeof(A) << endl;
cout << "size of P = " << sizeof(P) << endl;
even if the addresses (vaules A and P) are equal, compiler works with array (A) in a different way than with pointer: sizeof(A) means memory allocated for whole array (5 items of sizeof(int) each), but sizeof(P) means memory allocated for data type int * (pointer to int). So, sizeof(P) depends only on compiler and OS platform (e.g. pointer can be 32-bit or 64-bit), but sizeof(A) depends on size of item (int may be not 32 bits) and NUMBER OF ITEMS in the array.
And you can "go to the next item" with pointer:
P++;
cout << *P << endl;
but you are not able to do:
A++;
because A is not variable of pointer type (it is just similar in sense of "address of the first item"), and compiler will say you something like:
error : '++' needs l-value

Accessing char member variable address of a structure

I have a structure and i am trying to print the address of their member variables.
When tried to print the address of char member variable through &(f.c) i am not getting their address.
Here is the code:
struct foo
{
char c;
short s;
void *p;
int i;
};
int main()
{
cout << "Size of foo: " << sizeof(foo) << endl;
foo f;
cout << "Address of c: " << reinterpret_cast<void*>(&f.c) << endl;
cout << "Address of c: " << &(f.c) << endl;
cout << "Address of s: " << reinterpret_cast<void*>(&f.s) << endl;
cout << "Address of s: " << &(f.s) << endl;
cout << "Address of p: " << reinterpret_cast<void*>(&f.p) << endl;
cout << "Address of p: " << &(f.p) << endl;
cout << "Address of i: " << reinterpret_cast<void*>(&f.i) << endl;
cout << "Address of i: " << &(f.i) << endl;
return 1;
}
Output
/pp/cplus/bas ]$ ./a.out
Size of foo: 12
Address of c: 0xffbfe680
Address of c: //----------- &(f.c). Why this is empty..
Address of s: 0xffbfe682
Address of s: 0xffbfe682
Address of p: 0xffbfe684
Address of p: 0xffbfe684
Address of i: 0xffbfe688
Address of i: 0xffbfe688
just want to know why it is not printing when i tried accessing it through &(f.c)
Compiled using gcc version 3.4.6
cout has an operator<< overload for char* which treats the argument like a pointer to a C-string and it tries to print all the characters in that C-string until it gets to a NUL (0) byte. To get around this behaviour, you have to cast the addresses to void* like you are doing every other line.
You have just experienced the reason that arrays are sometimes considered second-class data types because they are treated specially in some situations (i.e. arrays of char are treated differently by some things but not others).
The Address of c: is empty because that's what you get when you try to print a string pointed to by &f.c. As dark_charlie pointed out, using an uninitialised variable is undefined behaviour, so technically anything can happen, but the former is probably the explanation for what you're seeing (though we can only guess).
The reason is that without the reinterpret cast &(f.c) is a char* pointer which is treated as a string by cout. Because you haven't filled the char with anything, you invoke an undefined behavior (i.e. it can print anything).