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]
Related
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.)
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
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
This question already has an answer here:
C++ parameter passing queries (code examples and outputs included)
(1 answer)
Closed 8 years ago.
First of all, i have no idea how to word the title whilst keeping it descriptive if anybody has a better idea feel free to edit.
My question is as follows; I have been given a set of function definitions and calls to these functions which currently operate using an int* as the variable that is being passed in various ways to these functions.
My task is to without changing the function definitions make the program compile and produce the same output but this time use an int over an int*.
Desired output:
Result
first 43
second 43
third 44
fourth 0
fifth 69
This is the code for the when the variable is an int*
void MyIncrementFirst(int* i) {
(*i)++;
}
void MyIncrementSecond(int i) {
i++;
}
void MyIncrementThird(int & i) {
i++;
}
void MyIncrementFourth(int** i) {
*i = new int(0);
}
void MyIncrementFifth(int*& i) {
i = new int(69);
}
int main(){
int* a = new int(42);
cout << "Result" << endl;
MyIncrementFirst(a);
cout << "first " <<*a << endl;
MyIncrementSecond(*a);
cout << "second " <<*a << endl;
MyIncrementThird(*a);
cout << "third " <<*a << endl;
MyIncrementFourth(&a);
cout << "fourth " <<*a << endl;
MyIncrementFifth(a);
cout << "fifth " <<*a << endl;
return 0;
}
Now here is what i have so far when changing the type of a to an int, not an int*:
Note: The function definitions are the same as above.
int main(){
int a = 42;
cout << "Result" << endl;
MyIncrementFirst(&a);
cout << "first " <<a << endl;
MyIncrementSecond(a);
cout << "second " <<a << endl;
MyIncrementThird(a);
cout << "third " <<a << endl;
/*
MyIncrementFourth(&a);
cout << "fourth " <<a << endl;
MyIncrementFifth(a);
cout << "fifth " <<a << endl;
*/
return 0;
}
Which prints:
Result
first 43
second 43
third 44
Calls to MyIncrementFourth and MyIncrementFith have been commented because i am not sure how to translate this to handle an int rather than an int*. Any attempts i do would just be fluke rather than knowledge.
Can anybody help me identify how to correctly complete the calls to MyIncrementFourth and MyIncrementFith in order to achieve a correct result.
Thanks,
Chris.
void foo(int a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
While with * it would be like this
void foo(int* a) {
...
}
int main() {
int a = 5;
foo(&a);
return 0;
}
However, this reminds of C.
You could use the & operator, instead of the *, like this:
void foo(int& a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
I assume you know what passing by value and by reference means. If you want a refresh, take a look in my example here.
[EDIT]
Also note that the code in the first block of yours is not OK, since you call new twice, but you never call delete.
Also, about what you are asking, you cannot do it without using an extra pointer. In other words, it can not be done by only having int a in the play.
Example:
int* a_pointer = &a;
MyIncrementFourth(&a_pointer);
cout << "fourth " << a << ", but a_pointer points to " << *a_pointer << endl;
Why the value of a did not change, despite the fact that we set the a_pointer to be equal with the address of a.
Because inside your function, you are calling new and as you know, it will return a pointer to the new allocated memory.
As a result, a_pointer is assigned a new value. Which value? The address of the new allocated memory.
When you use
int a = 42;
instead of
int* a = new int(42);
fourth and fifth function can't be used. The MyIncrementFourth and MyIncrementFifth (counterintuitive names, by the way) pretend to replace the pointer you allocated in the main with another pointer to another area, allocated inside the functions (and there will be a memory leak since you no longer will be able to delete the original a…). But if you stick to int a = 42 instead of int* a = new int(42), your variable is not a pointer, thus those functions have no pointer they can replace.
You can use:
int* ap = &a;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
// It does not change the value a.
You can also use:
int* ap = NULL;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
int* ptr;
MyIncrementFourth(&ptr);
a = *ptr;
delete ptr;
std::cout << "fourth " << a << std::endl;
MyIncrementFifth(ptr);
a = *ptr;
delete ptr;
std::cout << "fifth " << a << std::endl;
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;