Dynamic Memory Crash

Started by
8 comments, last by Hodgman 15 years, 11 months ago
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; }
Advertisement
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;
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; //#1storage = new int; //#2storage = new int; //#3storage = new int; //#4storage[0] = 5;//#5storage[1] = 7;//#6storage[2] = 2;//#7storage[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!!!
@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?
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<>
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.
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 << std::endl;	return 0;}


EDIT:
Bah, too slow x2!
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 integersstorage[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 memoryint *newStorage = new int[6];for( int i=0; i<4; ++i ){//copy the old data into the new memory  newStorage = storage;}delete [] storage;//delete the old memorystorage = newStorage;newStorage = 0;storage[4] = 9;storage[5] = 13;cout << "[4]: " << storage[4] << endl;cout << "[5]: " << storage[5] << endl;delete [] storage;storage = 0;}
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.
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...}

This topic is closed to new replies.

Advertisement