Dereferencing pointer to array when debugging in XCode 4.2 - c++

I'm using XCode to follow along in an intro to programming C++ class. No grade involved, I'm simply living vicariously through the eyes of others. Now that we've reached the subject of pointers I'm having trouble keeping track of where I am. If I pass a pointer to a dynamic array into a function how can I dereference that pointer to see what's actually being held in the various positions of the array. My code is compiling, but a couple of the functions are returning garbage. A clear indication that something isn't point to the right place.
Thanks in advance!
--John

It's likely that some code will be needed to further understand your problem, but from what I understood, here is what you need.
#include <iostream>
void f(int *array){
std::cout<<array[5];
}
int main(){
int* array = new int[10];
array[5] = 20;
f(array);
return 0;
}
This will print "20".

Related

&temp and *temp in c++

I am new to C++ and trying to convert string into integer. I was using atoi but there are some restrictions so I start using strtol which works perfectly. However, I would like to learn more on *temp and &temp (I have google and learn that it is a temporary space for storage) but would like to learn the difference and when to use which.
char *temp;
int m = strtol (argv[1],&temp,10);
if (*temp != '\0')
*temp is a pointer to a variable named temp and &temp takes the address of that variable
First of all jessycaaaa welcome to Stackoverflow.
I am new to C++ and trying to convert string into integer.
For me this looks like plain C-code. You can compile this with a C++ compiler though.
I was using atoi but there are some restrictions so I start using strtol which works perfectly.
Since you get an undefined behavior using atoi when argv[1] contains something different than a number, strtol is an approach to go for. If you share us a bit more code, we would help you better on your questions.
However, I would like to learn more on *temp and &temp (I have google and learn that it is a temporary space for storage) but would like to learn the difference and when to use which.
First of all you have to distinguish between use and declaration
char *temp;
Here you declare (*-symbol in declaration) a pointer named temp of type char. A pointer is a variable which stores the memory address (where it is pointing to). Here you did not define an address so it most likely will point a random space, but then
int m = strtol (argv[1],&temp,10);
you pass the address of the pointer (&-symbol, use-case, address-of operator) to strtol, so you get an address pointing to the part of the argv[1] where the number literals end, that is all fine. The function also returns the numerical value of the read string as long and is converted to an int.
if (*temp != '\0')
Here you access the value of what the address is pointing to (*-symbol, use-case, dereference operator). \0 is normally set as indication for a null-terminated string. So you are asking if the previously read end part has the null-termination character.
You know what: in C++ there are more elegant ways to accomplish that using stringstreams:
std::stringstream
Just an idea if you don't want to handle too much string manipulation in C and annoyances with pointers.
Also I would read a good book about C (not C++). C++ has also the references don't get confused by those. If you dominate the pointer-concept of C, I'm pretty sure everything else will be very clear for you.
Best regards
* and & are one of the first hurdles that programmers new to C and C++ have to take.
To really understand these concepts, it helps to know a bit more about how memory works in these languages.
First of all: C++ is just C but with classes and many other additional features. Almost all C programs are valid C++ programs. C++ even started out as a language that was compiled to C first.
Memory is, roughly speaking, divided in two parts, a 'stack' and a 'heap'. There are also other places for the code itself and compile-time constants (and maybe a few more) et cetera but that doesn't matter for now. Variables declared within a function always live on the stack. Let's see this in action with a simple example and analyse how memory is organized to build a mental model.
#include <iostream>
void MyFunction() {
int intOnStack = 5;
int* intPtrOnStack = new int(6); // This int pointer points to an int on the heap
std::cout << intOnStack << *intPtrOnStack;
delete intPtrOnStack;
}
int main() { MyFunction(); }
This program prints 56 when executed. So what happens when MyFunction() gets called? First, a part of the stack is reserved for this function to work with. When the variable intOnStack is declared within the function, it is placed in this part of the stack and it is initialized with (filled with) the int value 5.
Next, the variable intPtrOnStack is declared. intPtrOnStack is of type int*. int*'s point to int's by containing their memory-address. So an int* is placed on the stack and it is initialized with the value that results from the expression new int(6). This expression creates a new int on the heap and returns the memory-address of this int (an int*) to it. So that means that intPtrOnStack now points to the int on the heap. Though the pointer itself lives on the stack.
The heap is a part of memory that is 'shared' by all functions and objects within the program. The stack isn't. Every function has its own part of the stack and when the function ends, its part of the stack is deallocated.
So int*'s are just memory-addresses of int's. It doesn't matter where the int lives. int*'s can also point to int's on the stack:
#include <iostream>
void MyFunction() {
int intOnStack = 5;
int* intPtrOnStack = &intOnStack; // This int pointer points to intOnStack
std::cout << intOnStack << *intPtrOnStack;
}
int main() { MyFunction(); }
This prints 55. In this example we also see the &-operator in action (there are several uses of & like the bit-wise-and, I'm not going into them).
& simply returns the memory-address (a pointer!) of its operand. In this case its operand is intOnStack so it returns its memory-address and assigns it to intPtrOnStack.
So far, we've seen only int* as types of pointers but there exist pointer-types for each type of object that has a memory-address, including pointers. That means that a thing like int** exists and simply means 'pointer to a pointer to an int'. How would you get one? Like this: &intPtrOnStack.
Can pointers only live on the stack? No: new int*(&intPtrOnStack). Or new int*(new int(5)).

Correct pointer arithmetic in C

I am trying to learn pointer manipulation in C, and I am not understanding how part of the code isn't working.
#include <stdio.h>
int main() {
int *alpha[17];
*(alpha+4)= 35;
*(alpha+5)= 35;
*(alpha+12)= 50;
printf("%d", *(alpha+4));
*(alpha+8)=*(alpha+5) + *(alpha+12);
return 0;
}
Why is the line after the printf not working, and causing a crash, when the previous lines ran perfectly? I am trying to get the 9th value to equal the sum of the 6th and 13th value.
int *alpha[17]; creates array of pointers.
If you want array of int, use int alpha[17];
Your assignations are succesful because of implicit cast from int to pointer. (I hope you are getting warnings)
Adding two pointers is not only non-sensical, but also not allowed in C.
This post covers why adding two pointers is forbidden in C++, but arguiments are applicable to C also.
You have created an array of pointers but have not array of ints.
You should use:
int alpha[17];

Dealing with pointer arrays

I am playing around with arrays as pointers.
#include<iostream>
#include<cstring>
using namespace std;
int main(){
string *myarray[20];
*myarray[0]="Ich denke sein";
*myarray[1]="Ich sehe sein";
cout<<*myarray[0]<<endl;
cout<<*myarray[1]<<endl;
return 0;
}
The above code compiles but while executing, there is error, the program hangs. When I debugged using visual studio, it said memory allocation error. What is the error here?
As I know, I am dealing with values refered by pointers everywhere.
You have allocated an array of 20 pointers to strings. But you haven't allocated any memory for what the pointers point to. Rather than pursuing this and using new to allocate memory for the strings, it would be better instead to allocate memory for the strings themselves in the array and you will be fine.
string myarray[20];
myarray[0]="Ich denke sein";
myarray[1]="Ich sehe sein";
cout<<myarray[0]<<endl;
cout<<myarray[1]<<endl;
In response to your comment, to make your program work as is, set the pointer to point to a new string object
myarray[0]=new string("Ich denke sein");
myarray[1]=new string("Ich sehe sein");
The other lines of your program remain unchanged. Note
the remaining myarray[i], for 2<=i && i<20 will still be garbage. (It would be neater to set them to 0 or nullptr in a for loop.)
you also ought to delete the objects you've allocated. (You could use a for loop over the whole array to do this if you'd cleared the rest of the pointers first.)
as other answers have commented, in modern C++ it is best not to use pointers directly unless you absolutely have to. And you would also typically prefer to use a vector for arrays rather than using the built-in type (in C++11 the array type can be used for arrays where you know the length at compile time).
You have an array of uninitialized pointers:
string *myarray[20];
Then you treat it as if the pointers pointed to valid objects:
*myarray[0]="Ich denke sein";
This is undefined behaviour. It is unrelated to arrays. It is the same as doing this:
std::string* s;
*s = "boom!";
Besides that, you really should #include <string> if you want to use std::string.
First, you didn't include the right header. For string, you should:
#include <string>
Second, the program hangs because you're assigning data to where the pointer is pointing to. So where does myArray[0] point to? You don't know, I don't know, no one knows. It seems you didn't get the grasp of what pointers are all about, regardless of whether you're dealing with arrays of them or not.
To use a pointer, it must point somewhere valid. If you don't do that, then you can't dereference the pointer and assign data. It's that simple.
May be the problem is that those pointers aren't pointing to any addres in the memory. Pointers should be initialized to somewhere using the "address of operator" (&) or putting them in the free memory, using the "new" keyword, and if you do so, don't forget to free that memory using the "delete" keyword. Hope that works for you.
What is the error here?
The error is, that you are using pointers ;-)
#include <string>
#include <iostream>
int main() {
std::string myarray[2] = {
{ "Ich denke sein" }, { "Ich sehe sein" } };
std::cout << myarray[0] << std::endl;
std::cout << myarray[1] << std::endl;
return 0;
}
What is the reason behind using pointer? In C++ you mostly never use pointers.
Kind regards - Andreas
You have declared an array of 20 pointers. You will have to allocate memory to the pointer before assigning a value at the location to which it points.
string* myarray[20];
for(int i = 0; i < 20; i++) {
myarray[i] = new string();//allocating memory to the pointer
}
*myarray[0]="Ich denke sein";
*myarray[1]="Ich sehe sein";
cout<<*myarray[0]<<endl;
cout<<*myarray[1]<<endl;
Pointers are used to point to memory addresses, like this:
String text ="hello";
String *myptr = &text;
Now the pointer points to the address of the string text.
Or you can use new keyword to allocate memory for an array of pointers. new returns you a pointer to the first position of the array. Like this:
int *myptr = new int[20];
But remember to use delete, to deallocate the allocated memory later. Like this:
delete[] myptr

Programming with global variables giving wrong results

I've been coding for a while in other languages and am pretty proficient, but now I am diving more deeply into C++ and have come across some weird problems that I never had in other languages. The most frustrating one, which a google search hasn't been able to answer, is with two different code orders.
The background is that I have an array of integers, and a pointer an element in the array. When I go to print the pointer one method prints correctly, and the other prints nonsense.
An example of the first code order is:
#include <iostream>
using namespace std;
void main(){
int *pAry;
int Ary[5]={2,5,2,6,8};
pAry=&Ary[3];
cout<<*pAry<<endl;
system("pause");
}
and it works as expected. However this simple order wont work for the full project as I want other modules to access pAry, so I thought a global define should work, since it works in other languages. Here is the example:
#include <iostream>
using namespace std;
int *pAry;
void evaluate();
void main(){
evaluate();
cout<<*pAry<<endl;
system("pause");
}
void evaluate(){
int Ary[5]={2,5,2,6,8};
pAry=&Ary[3];
}
When I use this second method the output is nonsense. Specifically 1241908....when the answer should be 6.
First I would like to know why my global method isn't working, and secondly I would like to know how to make it work. Thanks
In the second example, Ary is local to the function evaluate. When evaluate returns, Ary goes out of scope, and accessing it's memory region results in undefined behaviour.
To avoid this, declare Ary in a scope where it will still be valid at the time you try to access it.
It's not working because your pAry is pointing into a local array, which is destroyed when you return from evaluate(). That's undefined behavior.
One possible fix is to make your local array static:
static int Ary[5]={2,5,2,6,8};
In the evaluate() function, you're aiming pAry at a variable (actually array element) local to that function. A pointer can only be dereferenced as long as the object to which it points still exists. Local objects cease to exist when they go out of scope; in this case, this means all elements of Ary cease to exist when evalute() ends, and thus pAry becomes a dangling pointer (it doesn't point anywhere valid).
Dereferncing a dangling pointer gives undefined behaviour; in your particular case, it outputs a garbage value, but it might just as well crash or (worst of all) appear to work fine until the program changes later.
To solve this issue, you can either make Ary global as well, or make it static:
void evaluate(){
static int Ary[5]={2,5,2,6,8};
pAry=&Ary[3];
}
A static local variable persists across function calls (it exists from first initialisation until program termination), so the pointer will remaing valid.
The problem is that you need to declare Ary with file scope.
int Ary[] = {1,2,3,4,5};
void print_ary(void); // The void parameter is a style thingy. :-)
int main(void)
{
print_ary();
return EXIT_SUCCESS;
}
void print_ary(void)
{
for (unsigned int i = 0; i < (sizeof(Ary) / sizeof(Ary[0]); ++i)
{
std::cout << Ary[i] << std::endl;
}
}
A better solution would be to pass a std::vector around to your functions rather than using a global variable.

Address of address of array

If I define an variable:
int (**a)[30];
It is pointer. This pointer points to a pointer which points to an array of 30 ints.
How to declare it or initialize it?
int (**a)[10] = new [10][20][30];
int (**a)[10] = && new int[10];
All doesn't work.
The direct answer to your question of how to initialize a (whether or not that's what you actually need) is
int (**a)[10] = new (int (*)[10]);
I don't think this is actually what you want though; you probably want to initialize the pointer to point to an actual array, and either way std::vector is the better way to do it.
If you want an answer to the question as it stands, then you can do this kind of thing:
int a[30];
int (*b)[30] = &a;
int (**c)[30] = &b;
But it's unlikely to be what you want, as other people have commented. You probably need to clarify your underlying goal - people can only speculate otherwise.
Just to follow on from MooingDuck's remark, I can in fact see a way to do it without the typedef, but not directly:
template <typename T>
T *create(T *const &)
{
return new T;
}
int (**a)[30] = create(a);
It's not pretty though.
What do you expect to get by writing &(&var)? This is an equivalent of address of address of a block of memory. Doing things like this just to satisfy the number of * in your code makes no sense.
Think about it - how can you get an address of an address? Even if, by some sheer luck or weird language tricks you manage to do it, there no way it will work.