Sign in to follow this  
Dhaos

Dynamic Memory Crash

Recommended Posts

Dhaos    122
I has a wittle problem. When I run this test I made, it runs, shows all the variables correctly, however it brings up an error message after it runs then exits. This leads me to believe there is something I don't understand about dynamic memory allocation. Note that if I use the array version (the commented out bits) it works fine, UNLESS I do storage = new int[1], I get the same crash. Somebody please fill me in on yet another simple concept that eludes me. Thankies. *Also if I just delete storage like I do at the end, does that free up all the "new ints" as well? Or do I need to delete each element individually? #include <iostream.h> int *storage = 0; void main() { //storage = new int[4]; storage = new int; storage = new int; storage = new int; storage = new int; storage[0] = 5; storage[1] = 7; storage[2] = 2; storage[3] = 6; cout << "[0]: " << storage[0] << endl; cout << "[1]: " << storage[1] << endl; cout << "[2]: " << storage[2] << endl; cout << "[3]: " << storage[3] << endl; //storage = new int[2]; storage = new int; storage = new int; storage[4] = 9; storage[5] = 13; cout << "[4]: " << storage[4] << endl; cout << "[5]: " << storage[5] << endl; delete storage; *storage = 0; }

Share this post


Link to post
Share on other sites
Tenac    124
What if you uncomment the first line in main() and delete the next 4 lines after it? Along with the //storage = new int[2];

EDIT: or maybe delete[] storage;

Share this post


Link to post
Share on other sites
Hodgman    51222
Quote:
Original post by Dhaos
I has a wittle problem. When I run this test I made, it runs, shows all the variables correctly, however it brings up an error message after it runs then exits.

You're probably getting an error message because your program is randomly overwriting bits of memory that it doesn't have permission to access!

Quote:
Original post by Dhaos
Note that if I use the array version (the commented out bits) it works fine, UNLESS I do storage = new int[1], I get the same crash. Somebody please fill me in on yet another simple concept that eludes me. Thankies.

Your "array version" is the correct way to do it! Except you need to replace "delete storage; *storage = 0;" with "delete [] storage; storage = 0;".

Quote:
*Also if I just delete storage like I do at the end, does that free up all the "new ints" as well? Or do I need to delete each element individually?

You need one 'delete' for every 'new' (or one 'delete []' for every 'new []').

They way that you're currently doing it you can't possibly delete all the integers, because you're throwing away the addresses of most of them ;)

Here's an explanation of what your code is actually doing:
Quote:
storage = new int; //#1
storage = new int; //#2
storage = new int; //#3
storage = new int; //#4

storage[0] = 5;//#5
storage[1] = 7;//#6
storage[2] = 2;//#7
storage[3] = 6;//#8


#1 allocate a single integer and store the address in storage.

#2 allocate a single integer and store the address in storage (ERROR: overwriting the address of the int that was allocated at #1, making the previous int impossible to delete!)
#3 allocate a single integer and store the address in storage (ERROR: overwriting the address of the int that was allocated at #2, making the previous int impossible to delete!)
#4 allocate a single integer and store the address in storage (ERROR: overwriting the address of the int that was allocated at #3, making the previous int impossible to delete!)

#5 access the integer that is pointed to by the address in storage, and store the number 5 in it

#6 ERROR! Access the 4 bytes of memory that happen to be located right after the memory that was allocated at #4! You don't own this memory!!!
#7 ERROR! Access the 4 bytes of memory that happen to be located 4 bytes after the memory that was allocated at #4! You don't own this memory!!!
#8 ERROR! Access the 4 bytes of memory that happen to be located 8 bytes after the memory that was allocated at #4! You don't own this memory!!!


Quote:
delete storage; //#1
*storage = 0; //#2


#1 Give back the memory at the address stored in storage
#2 ERROR! Access the memory that you've already given back, and set it to zero! You don't own this memory anymore!!!

Share this post


Link to post
Share on other sites
Dhaos    122
@tenac: Yes.

@Hodgman: Ok, so it seems I really messed things up. I am *trying* to make an array that grows in size when needed. I am now lost at how this is done. Are linked lists the only way to do this?

Share this post


Link to post
Share on other sites
fpsgamer    856
Quote:
Original post by Dhaos
@tenac: Yes.

@Hodgman: Ok, so it seems I really messed things up. I am *trying* to make an array that grows in size when needed. I am now lost at how this is done. Are linked lists the only way to do this?


std::vector<>

Share this post


Link to post
Share on other sites
Tenac    124
I suggest a vector then.

#include <vector>
std::vector<int> storage;

http://www.cplusplus.com/reference/stl/vector/

EDIT: I hate getting beat to a post when they are the same answer lol, but mine has more words and detail =P.

Share this post


Link to post
Share on other sites
fastcall22    10838
You can use std::vector:


#include <iostream>
#include <vector>

int main( int, char** )
{
std::vector<int> array( 3 ); // equivalent to new int[3];

array[0] = 13;
array[1] = 64;
array[2] = 43;

array.resize( 5 );

array[3] = 34;
array[4] = 53;

for ( int i = 0; i < 5; i++ )
std::cout << "array[" << i << "] = " << array[i] << std::endl;

return 0;
}





EDIT:
Bah, too slow x2!

Share this post


Link to post
Share on other sites
Hodgman    51222
Quote:
Original post by Dhaos
I am *trying* to make an array that grows in size when needed. I am now lost at how this is done. Are linked lists the only way to do this?

C++ has a built-in resizable array called std::vector.

Or if you want to do it yourself, it would look something like this:

void main()
{
int *storage = new int[4];//start off with 4 integers

storage[0] = 5;
storage[1] = 7;
storage[2] = 2;
storage[3] = 6;

cout << "[0]: " << storage[0] << endl;
cout << "[1]: " << storage[1] << endl;
cout << "[2]: " << storage[2] << endl;
cout << "[3]: " << storage[3] << endl;

//add two more integers, gotta allocate new memory
int *newStorage = new int[6];
for( int i=0; i<4; ++i )
{//copy the old data into the new memory
newStorage[i] = storage[i];
}
delete [] storage;//delete the old memory
storage = newStorage;
newStorage = 0;

storage[4] = 9;
storage[5] = 13;

cout << "[4]: " << storage[4] << endl;
cout << "[5]: " << storage[5] << endl;

delete [] storage;
storage = 0;
}


Share this post


Link to post
Share on other sites
Dhaos    122
Ok, that wasn't quite what I was looking for. I'll elaborate more on the issue. I wrote a d3d app, and I need to pass a dynamically allocated array into the video card memory.

void* p_void;//stores first type pointed to
d3d_buffer_vertex_model->Lock(0,0,(void**)&p_void,0);
memcpy(p_void, Model_Vertice, sizeof(Model_Vertice));
d3d_buffer_vertex_model->Unlock();
delete p_void;
p_void = 0;

Model_Vertice is currently a static array, a big one at that. If I use a linked list or vector, it seems there would be a lot of garbage data that would need to be discarded since directx only wants the vertex format data.

Currently I'm using D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE and to my knowledge I can ONLY pass that data into memory. Linked lists have the pointer to the next node, and vectors have a lot of other "stuff" as well.

Any input on this dilemma would be greatly appreciated.

The only hack job I could think of is creating a buffer pointer that would store the "old size" of the previous Model and then fill it into the "new size" while deleting the old.

Share this post


Link to post
Share on other sites
Hodgman    51222
Quote:
Original post by Dhaos
Linked lists have the pointer to the next node, and vectors have a lot of other "stuff" as well.


Linked lists of vertices won't work, but you can get a regular array (with no "stuff") out of a vector:


#include <vector>

struct MyFVF
{
MyFVF( float X, float Y, float Z ) : x(X), y(Y), z(Z) {]
float x,y,z;
//etc...
}

typedef std::vector<MyFVF> VertexList;

int main()
{
VertexList verts(3);
verts[0] = MyFVF(0,10,50);
verts[1] = MyFVF(10,0,50);
verts[2] = MyFVF(-10,0,50);

MyFVF* = &verts[0];//No "vector stuff", just the raw array...
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this