Copy contents of one array to another with pointers - c++

I've been learning C++ on my own for a while now, and I've come to a "roadblock" when it comes to pointers. I'm using this as my http://www.cplusplus.com/doc/tutorial/pointers/ learning material, but I'm still having an issue. So to test something I wanted to copy the contents of one array into another. I wrote the following.
char arrayA[15] = "abcdef";
char arrayB[15];
char *a = arrayA;
char *b = arrayB;
cout << "before loop:" << endl;
cout << a << endl;
cout << b << endl;
while (*a != '\0') {
// Copy the contents of a into b
*b = *a;
// Step
a++;
b++;
}
// Assign null to the end of arrayB
*b = '\0';
cout << "after loop:" << endl;
cout << a << endl;
cout << b << endl;
I get the following results.
before loop:
abcdef
after loop:
When I cout the contents before the loop I get the expected results. a contains "abcdef" and b is nothing, because there is no value yet. Now after the loop, both a and b show no results. This is where I am lost. I used * to dereference both a and b and assign the value of a into b. Where did I go wrong? Do I need to use the & with this?
Solution:
After the loop is complete, pointer *a is pointing to the end of arrayA and pointer *b is pointing to the end of arrayB. So to get the full results of arrayB simply cout << arrayB. Or create a pointer that never changes and always points to arrayB char *c = arrayB and cout << c at the end of the loop.

After the loop a and b have changed, they then point to the end of the string. You need to make a copy of the pointers to step through so that as you iterate you're not changing the location of a and b.

The problem is that you're outputting your temporary variables that were used to iterate through the array. They are now at the end of the copied data. You should output the value of arrayA and arrayB instead.

Remember begin of array. In this moment you are incrementing pointers and printing something which is pointed by them at the end of arrays, after loop ends.
char arrayA[15] = "abcdef";
char arrayB[15];
char *a_beg = arrayA;
char *b_beg = arrayB;
char *a;
char *b;
cout << "before loop:" << endl;
cout << a_beg << endl;
cout << b_beg << endl;
a = a_beg;
b = b_beg;
while (*a != '\0') {
// copy contents of a into b and increment
*b++ = *a++;
}
// assign null to the end of arrayB
*b = '\0';
cout << "after loop:" << endl;
cout << a_beg << endl;
cout << b_beg << endl;

Related

New allocates the same memory with each iteration

I am trying to build a list-like heap storage of C-strings.
This is a simplified part of the program.
However, with each iteration new brings up the same address.
#include <iostream>
class listStringContainer {
public:
listStringContainer(const char* c);//constructor
};
int main(){
listStringContainer lsc1 ("Lorem ipsum");// calling the constructor
}
listStringContainer::listStringContainer(const char* c) {//constructor
char * Memory_Address;
auto time{5};
while (--time>=0) {
Memory_Address = new char[16];
//the memory location is to be saved into a vector
std::cout << "Memory_Address: "<< &Memory_Address << std::endl;
}
}
Output:
Memory_Address: 0x62fed8
Memory_Address: 0x62fed8
Memory_Address: 0x62fed8
Memory_Address: 0x62fed8
Memory_Address: 0x62fed8
The same result on g++ and MSVS.
Why does new appoint the same location and how to make new appoint different addresses?
You need to cast the static_cast<void*>(Memory_Address) to get the value stored in Memory_Address.
Lets consider:
char * p;
p= new char[16];
strcpy(p, "Hello");
cout << *p << endl; // Prints 'H'
cout << &p << endl; // Prints address of p
cout << p << endl; // Prints "Hello"
cout << static_cast<void*>(p) << endl; // Prints address of p[0]
Consider the below same scenario but with Integer data type:
int * ptr;
ptr= new int[16];
ptr[0] = 10;
cout << *ptr << endl; // Prints 10
cout << &ptr << endl; // Prints ptr address
cout << ptr << endl; // Prints address of ptr[0]
Therefore, Integer doesn't require casting to void* for getting &ptr[0]

Outputting succesive addresses of members of arrays

I drew this for a better understanding. In the PC's memory there are succesive memory zones with length of 1 byte ( the green ones ). They can be grouped for representing bigger data ( as an int in our example ).
What i want to add to this picture is that the green squares are succesive addresses like 0x000000 followed by 0x000001 etc. Then the addresses from arr are jumping by four like 0x000000 and the next one would be 0x000004 ( because an int in this care is 4bytes ).
The code_1:
int arr[4] = {1,2,3,4};
int *p = arr;
cout << p << endl;
cout << ++p << endl;
cout << ++p << endl;
cout << ++p << endl;
The output_1:
0x69fedc
0x69fee0
0x69fee4
0x69fee8
The code_2:
char arrr[5] = {'1','2','3','4', '\n'};
char *ptr = arrr;
cout << &ptr << endl;
cout << &(++ptr) << endl;
cout << &(++ptr) << endl;
cout << &(++ptr) << endl;
The output_2:
0x69fed0
0x69fed0
0x69fed0
0x69fed0
The problem:I expect in output_2 i expect that the addresses would be 0x69fed0,0x69fed1,0x69fed2,0x69fed4
This is because you are displaying the address of the pointer instead of the address stored in the pointer:
char *ptr = 0;
std::cout << &ptr; // address where the pointer is placed
std::cout << (void*)ptr; // address managed by the pointer = 0
++ptr;
std::cout << &ptr; // this value never changes
std::cout << (void*)ptr; // Now this value should be 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

Array of pointers unexplained behavior (with shallow copy) c++

This is a behavior with array of pointers in C++ (GNU GCC compiler) that I can't find an explanation for, hopefully someone can clear the confusion.
I'm creating an array of pointers (arr_ptr), The pointers are pointing to valid data, then I create another array of pointers (arrcopy), I do -what I think- a shallow copy (arrcopy = arr_ptr), and I get the data as expected...so far so good.
The part I am not understanding is, after I delete arr_ptr, shouldn't arrcopy still be pointing to my valid data? Why this is not happening?
Thank you.
int main()
{
int a = 1; int b=2; int c=3;
int* ap = &a; int* bp = &b; int* cp = &c;
// Array of pointers
int** arr_ptr = new int*[3];
arr_ptr[0] = ap;
arr_ptr[1] = bp;
arr_ptr[2] = cp;
//shallow copy
int** arrcopy = arr_ptr;
cout << "Values: " << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl;
cout << "Addresses: " << arr_ptr[0] << " " << arrcopy[0] << endl;
cout << endl;
a++;
cout << "After Incrementing a:" << endl;
cout << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl;
cout << arr_ptr[0] << " " << arrcopy[0] << endl;
cout << endl;
*(arr_ptr[0]) = 5;
cout << "After updating a value to 5:" << endl;
cout << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl;
cout << arr_ptr[0] << " " << arrcopy[0] << endl;
cout << endl;
//so far so good - works as expected
//deleting arr_ptr
delete[] arr_ptr;
// Why?: shouldn't arrcopy still be pointing to A
cout << "Values: " << *(arr_ptr[0]) << " " << *(arrcopy[0]) << endl; //The result I am expecting here is: unknown_value 5
cout << "Addresses: " << arr_ptr[0] << " " << arrcopy[0];
cout << endl;
return 0;
}
After Shallow copy of arr_ptr to arrcopy (arrcopy = arr_ptr)
After deleting arr_ptr, shouldn't arrcopy still be pointing to the memory locations of a,b,c data values?!
You do not have 2 arrays after the assignment you have 2 pointers to the same array:
arr_ptr -------->|ptr0|ptr1|ptr2|ptr3... (allocated memory)
arr_cpy = arr_ptr; // copy only the pointer
Now both pointers point to the same allocated memory:
arr_ptr -------->|ptr0|ptr1|ptr2|ptr3...
^
arr_cpy -----------|
delete[] arr_ptr; // invalidate the memory that both pointers point to
This gives:
arr_ptr -------->|xxx0|xxx1|xxx2|xxx3... (invalid memory)
^
arr_cpy -----------|
It doesn't matter which pointer you call delete[] on, they both point to the same block of allocated memory so after the call they both point to the same block of invalidated memory.
What you need to do is copy the whole array:
int** arr_cpy = new int*[3];
std::copy(arr_ptr, arr_ptr + 3, arr_cpy); // copy the pointers to the new array
Or much better use a std::vector:
int main()
{
int a = 1; int b=2; int c=3;
int* ap = &a; int* bp = &b; int* cp = &c;
// Array of pointers
std::vector<int*> arr_ptr{3};
arr_ptr[0] = ap;
arr_ptr[1] = bp;
arr_ptr[2] = cp;
//shallow copy
std::vector<int*> arr_cpy = arr_ptr; // copy the whole vector
// ... etc.
No need for delete[], memory is deallocated automatically when your vector goes out of scope.
Neither arr_ptr nor arrcopy is an array. Both are just pointers.
A C++ pointer is a little overloaded. It can point to a single object or to an array of objects.
In your case arr_ptr is initialized with the address of the array that you allocated in the dynamic memory. But it could as well be initialized with an address of a single object on the stack:
int i = 0;
int** arr_ptr = &i;
By copying the value of that pointer into another pointer of the same type you simply have two pointers referring to the same memory location:
// array in the heap
[xxxxxxxxxxxxxxxxxxxxxxx]
^
/ \
/ \
/ \
arr_ptr arrcopy

pointer to array 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;