Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 25 Mar 2012 08:44 AM |
Hi,
I have a few questions about pointers and dynamic memory allocation.
1. I read that *(myArray + 1) is the same as myArray[1]. Does that mean that myArray == address of myArray[0]
2. In dynamic memory allocation for arrays, we can create a new array with a non-constant value for the amount of indexes:
int size = 5; int *array = new int[size];
is the reason for this is because if you were to declare a new array, and the size had to be constant, you would usually have to declare a new constant value? If that's the case, why can't we just have non-constant values for the size, whether it's new or not?
3. How is this a problematic program, that will cause the program to crash?
int *value = new int; delete value;
if (value) *value = 5;
..the reason I don't see the problem is that 'value' will evaluate to nil, after the delete, correct? Then, for some reason, the 'if' condition will evaluate to true (why? it's nil), and then set the 'value' variable to 5. How would this cause a crash? ------ I may have more questions coming up.. because I read moar and I ask moar.. .-. |
|
|
| Report Abuse |
|
|
Legend26
|
  |
| Joined: 08 Sep 2008 |
| Total Posts: 10586 |
|
|
| 25 Mar 2012 09:06 AM |
1) Yea, it does. Array variables are just pointers. 2) Probably because it allows us to get input from the user. I don't think changing the value after creating the array changes anything. Ask myrkos. 3) It didn't crash for me, but you're essentially using memory you don't own which can cause problems if another program tries to use it. You're deleting "value" but you haven't set value to nullptr or 0. |
|
|
| Report Abuse |
|
|
Varp
|
  |
| Joined: 18 Nov 2009 |
| Total Posts: 5333 |
|
|
| 25 Mar 2012 09:33 AM |
3. Because you're using delete wrongly. Delete does not change the value of "value"; it merely deletes the memory it points to. So, after that line, you have a pointer to memory that was deleted. You should do:
int* value = new int;
delete value; //Value is unchanged, but it no longer owns its memory value = 0; //Value is set to NULL (sometimes NULL is also a keyword).
if (value) *value = 5;
|
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 25 Mar 2012 10:05 AM |
@Varp,
So 'value' just contains an address that means nothing, and that evaluates to true for the 'if' condition?
@Legend26,
Okay, lets hope myrkos sees this.. |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 25 Mar 2012 11:10 AM |
1. Arrays aren't actually pointers, but in most cases they act VERY similarly. It's just part of the language that you can access pointers as arrays. Arrays even "decay" to pointers when passed to functions etc.
2. I'm not exactly sure what you're asking here, but I think there are a few things that can be said. First, the difference between the two arrays is that one is on the stack and the other on the heap. Now, making a dynamic array on the stack (int a[x];) isn't supported by the C++ standard because it complicates stuff internally and people in the committee don't find much of a use for it that outweighs the bad stuff. The new C standard, C99, supports this. Did I kinda answer your question?
:O |
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 25 Mar 2012 02:48 PM |
@myrkos,
1. What do you mean? It would make sense that every array is a pointer to it's element at index 0. Could you explain more on how they are similar, and what makes them different?
2. I was reading on LearnCpp, that you can create a new array with a non-constant size. For example, normally, you would have an array like this:
const int size = 5; int myArray[size]; // it's a constant
..but instead, it said, when dynamically creating a new array, you can do this:
int size = 5; int myArray[size]; //not constant |
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 25 Mar 2012 03:01 PM |
I think I pretty much answered my third question, but like always, I still have a question.
When not zeroing a pointer after being deleted, does the pointer itself become deallocated memory, or is just the thing it is pointing too? I believe, the pointer becomes deallocated memory itself, so why is it bad to assign another value to the pointer? |
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
| |
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 25 Mar 2012 05:48 PM |
1. They're different in the sense that the pointer variable holds the address to an array, while an array variable is the first element of the array. For most practical purposes you can consider them to be the same thing, though.
2. Are you sure that works? Try making it a truly dynamic variable, because in your example it will always be 5, so the compiler may allow it for that reason.
3. The pointer points to deallocated memory. The pointer itself is still a valid variable, you just don't have permission to access the memory it points to anymore. |
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 25 Mar 2012 06:09 PM |
@myrkos,
For #2, I just got that off of Learncpp, so I guess it's right.. thanks though! |
|
|
| Report Abuse |
|
|
booing
|
  |
| Joined: 04 May 2009 |
| Total Posts: 6594 |
|
|
| 25 Mar 2012 06:24 PM |
As labeled, * is dereferencing. It makes something reference another address instead of the address of the memory C/C++ told it to point to. Sort of answers 1)? |
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 25 Mar 2012 06:43 PM |
Alright, what's wrong with this code (goes non-responsive):
int *value1 = 0; value1 = new int; cout << value1 << "\t" << *value1;
delete value1; cout << value1 << "\t" << *value1; value1 = 0; cout << value1 << "\t" << *value1;
------ And this code runs properly:
int *p_var = 0; // new pointer declared p_var = new int; // memory dynamically allocated cout << p_var << "\t" << *p_var << "\n";
delete p_var; // memory freed up cout << p_var << "\t" << *p_var << "\n"; p_var = 0; // pointer changed to 0 (null pointer) |
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 25 Mar 2012 06:46 PM |
O_O, I figured it out! Somehow, you cannot output:
*value1
after being zeroed. Now why in the world is it like this?! |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 25 Mar 2012 06:46 PM |
delete value1; cout << value1 << "\t" << *value1; // Here you're trying to access memory at the location you no longer have allocated value1 = 0; cout << value1 << "\t" << *value1; // Here you're trying to access memory at address 0. |
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 25 Mar 2012 06:51 PM |
So accessing memory after a delete, but before a zero is fine (it prints the same as if not deleted), but accessing memory AFTER zeroing is bad because *value1 is unresponsive..
delete value1; cout << value1 << "\t" << *value1 << "\n"; //this is fine, it prints the same result as the first one value1 = 0; cout << *value1 << "\n"; //this causes non-responsiveness |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 25 Mar 2012 06:56 PM |
| It's not "fine" at all. It's undefined behavior. Just because it works doesn't mean it should and always will work. The second actually blows up because your program has not been assigned the memory at location 0. The first hasn't blown up yet but it may anytime. |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 25 Mar 2012 07:02 PM |
For the only purpose of understanding pointers it might make sense to think of them as variables that store locations, or indexes, to a huge array (aka RAM). You only have permission to access locations that have been assigned to you. There's an area in the array, called the heap, where you can request certain amounts of memory to be assigned to you, like rooms in a hotel. The delete keyword gives that away and says you don't need it anymore. If you try to access it afterwards, the hotel keeper may have given the room to someone else, and you will be considered a thief. Room at location 0 (as in many other areas not in the heap) is reserved for the hotel staff.
ogm i should make this into a tutorial |
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 25 Mar 2012 07:04 PM |
@myrkos,
I just read that the reason the first one doesn't blow up is because value1 is null. If it weren't null, it would blow up. |
|
|
| Report Abuse |
|
|
myrkos
|
  |
| Joined: 06 Sep 2010 |
| Total Posts: 8072 |
|
|
| 25 Mar 2012 07:06 PM |
| value1 is NOT null. Only after it's zeroed out is it null, for null == 0. |
|
|
| Report Abuse |
|
|
|
| 25 Mar 2012 07:08 PM |
@flurite: You got that backwards. The reason the first one doesn't crash and burn is because it is _not_ NULL. When you say "delete value1", value1 still points to the mem address, but the address has been freed, so that if another program needs more memory, it can take that place. When you say "value1 = 0", you ARE setting value1 to NULL (NULL == 0), so the program will break if you try and read anything from that mem address. |
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
| |
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 25 Mar 2012 07:13 PM |
@yacker3000 and myrkos,
Thanks, everything pretty much makes sense now! |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 25 Mar 2012 07:18 PM |
"_const int size = 5; int myArray[size]; // it's a constant int size = 5; int myArray[size]; //not constant"
Neither of those should work in a standards conforming C/C++ compiler. The _Only_ way that they should work is if you do this:
int constexpr size = 5;
Which forces the compiler to evaluate the expression as a compile-time constant, or throw a fatal error if it can't. The given size of an array must be known at compile time unless you are dynamically allocating it with new. If you're willing to look at non-standard extensions then most C compilers have support for "Variable Length Arrays" but not in the sense that you were giving there. With that extension if you give an array at the end of a structure no size then it's size will take up all of the extra allocated space in the structure when you dynamically allocate it. |
|
|
| Report Abuse |
|
|
Flurite
|
  |
| Joined: 03 Apr 2011 |
| Total Posts: 5386 |
|
|
| 26 Mar 2012 02:10 PM |
@stravant,
According to LearnCpp, this works:
const int size = 5; int myArray[size];
..but as I mentioned, this wouldn't work:
int size = 5; int myArray[size]; |
|
|
| Report Abuse |
|
|