-
September 7th, 2011, 01:56 PM
#1
C++ vector length error at run time
Hi,
I'm having a problem with vectors, its the first time i'm using this structure so i'm probably missing something obvious.
What i'm trying to do is, create a class with a vector as a member, my code compiles with no errors but 4 warnings ... also to do with another vector.
the code compiles, but when debugging there is an error: vector<T> too long... also it says std::length_error at memory location 0x0030f1d8..
Just to explain my code, i'm trying to implement a bfs search for the 8 puzzle problem. I feel logically my code is correct and so i have not posted everything. Also it is a lot to read, but i have posted all the bits concerning the vectors.
I would appreciate any help!! thanks in advance!
here is my code:
my header file:
Code:
#ifndef HEADER_H
#define HEADER_H
#include <vector>
using std::vector;
class node{
public:
int state[3][3];
int id;
char action;
vector<int> list;
node* parent;
node();
~node();
};
#endif
file with definitions:
Code:
#include "header.h"
#include <iostream>
node::node() { list.reserve(10); }
node::~node() { }
and the main file
Code:
#include <stdio.h>
#include <iostream>
#include <string>
#include "header.h"
int choice;
int i,j,x,y,a,b,c,d,aa, children, start, stop, child;
int InState [3][3];
int GoalState [3][3];
bool leave = false;
char moves[4];
std::vector<int> final;
using namespace std;
int main(){
GoalState[0][0] = 1;
GoalState[0][1] = 2;
GoalState[0][2] = 3;
GoalState[1][0] = 8;
GoalState[1][1] = 0;
GoalState[1][2] = 4;
GoalState[2][0] = 7;
GoalState[2][1] = 6;
GoalState[2][2] = 5;
cout<<"Welcome to the 8-puzzle"<<endl;
cout<<"Our goal state is :"<<endl;
cout<<endl;
for (i=0; i<3; i++){
cout<<GoalState[i][0]<<" "<<GoalState[i][1]<<" "<<GoalState[i][2]<<endl;
}
cout<<"\nEnter Initial State one integer at a time:"<<endl;
cout<<"Please use integers 0 to 8 only where 0 represents the blank tile"<<endl;
for (i = 0; i<3; i++) {
for (j=0; j<3; j++){
cin>> InState[i][j];
if (InState[i][j] > 8) {
cout<<"number should be from 0 to 8. Re-enter"<<endl;
cin>> InState[i][j];}
}
}
//at this point we find the position of zero or the blank
for (i = 0; i<3; i++) {
for (j=0; j<3; j++){
if (InState[i][j] == 0){
x = i;
y = j;
}
}
}
cout<<"x "<< x <<"y "<< y <<endl;
cout<<"The initial state selected is"<<endl;
for (i=0; i<3; i++){
cout<<InState[i][0]<<" "<<InState[i][1]<<" "<<InState[i][2]<<endl;
}
//reserve for final path
final.reserve(10);
//define the root node
node root;
for (int i = 0; i<3; i++) {
for (int j=0; j<3; j++){
root.state[i][j] = InState[i][j];
}
}
root.id=0;
//start vector list to find path to goal
root.list.push_back(root.id);
//find available moves for root
zero_state(x,y,moves);
/*cout<<"Available moves:"<<endl;
for (i=0; i<sizeof(moves); i++){
cout<<moves[i]<<endl;
}*/
aa=sizeof(moves);
a = aa;
//generate number of children from root, using the number of available moves
node *levela;
try {
levela = new node[aa];
} catch (bad_alloc xa) {
cout<<"Allocation Failure\n";
return 1;
}
if (leave!=true){
//********************put this in a do while loop.... must continue until goal is found*******
//max depth?????
//for each child of root generate their children the same way
for (int i=0; i<aa; i++){
//fill each node with required information
levela[i].id = i+1;
//find available moves for each child
zero_position(levela[i].state,x,y);
zero_state(x,y,moves);
//define their parent
levela[i].parent=&root;
//define their states
copy(levela[i].state,root.state);
swap_tiles(levela[i].state,moves[i],x,y);
//define path to state
levela[i].list=root.list;
levela[i].list.push_back(levela[i].id);
// total number of children for all nodes at this level
children+=sizeof(moves);
//determine if goal state reached?
if (repeat_goal(levela[i].state,GoalState)) {
final=levela[i].list;
leave=true;
break;
}
}
}
//define children for each node
start=aa;
int bb=children;
node *levelb;
try {
levelb = new node[bb];
} catch (bad_alloc xa) {
cout<<"Allocation Failure\n";
return 1;
}
if (!leave){
children=0;
for (int j=0; j<start; j++){
//determine parent node moves
zero_position(levela[j].state,x,y);
zero_state(x,y,moves);
child=sizeof(moves);
aa+=child;
// total number of children for all nodes at this level
children+=sizeof(moves);
for (int jj=0; jj<child;jj++){
//fill each node with required information
levelb[jj].id = start+jj;
//define their parent
levelb[jj].parent=&levela[j];
//define their states
copy(levelb[jj].state,levela[j].state);
swap_tiles(levelb[jj].state,moves[jj],x,y);
//define path to state
levelb[jj].list=levela[j].list;
levelb[jj].list.push_back(levelb[jj].id);
//determine if goal state reached?
if (repeat_goal(levelb[jj].state,GoalState)) {
final=levelb[jj].list;
leave=true;
break;
}
}
}
b=aa-start;
}
//define children for each node
int cc=children;
node *levelc;
//levelc = new node[cc];
try {
levelc = new node[cc];
} catch (bad_alloc xa) {
cout<<"Allocation Failure\n";
return 1;
}
if (!leave){
stop=aa;
children=0;
for (int k=start; k<stop; k++){
//determine parent node moves
zero_position(levelb[k].state,x,y);
zero_state(x,y,moves);
child=sizeof(moves);
aa+=child;
// total number of children for all nodes at this level
children+=sizeof(moves);
for (int kk=0; kk<child;kk++){
//fill each node with required information
levelc[kk].id = stop+kk;
//define their parent
levelc[kk].parent=&levelb[k];
//define their states
copy(levelc[kk].state,levelb[k].state);
swap_tiles(levelc[kk].state,moves[kk],x,y);
//define path to state
levelc[kk].list=levelb[k].list;
levelc[kk].list.push_back(levelc[kk].id);
//determine if goal state reached?
if (repeat_goal(levelc[kk].state,GoalState)) {
final=levelc[kk].list;
leave=true;
break;
}
}
}
c = aa-stop;
}
//define children for each node
int dd=children;
node *leveld;
//leveld = new node[dd];
try {
leveld = new node[dd];
} catch (bad_alloc xa) {
cout<<"Allocation Failure\n";
return 1;
}
if (!leave){
start=stop;
stop=aa;
children=0;
for (int k=start; k<stop; k++){
//determine parent node moves
zero_position(levelc[k].state,x,y);
zero_state(x,y,moves);
child=sizeof(moves);
aa+=child;
// total number of children for all nodes at this level
children+=sizeof(moves);
for (int kk=0; kk<child;kk++){
//fill each node with required information
leveld[kk].id = stop+kk;
//define their parent
leveld[kk].parent=&levelc[k];
//define their states
copy(leveld[kk].state,levelc[k].state);
swap_tiles(leveld[kk].state,moves[kk],x,y);
//define path to state
leveld[kk].list=levelc[k].list;
leveld[kk].list.push_back(leveld[kk].id);
//determine if goal state reached?
if (repeat_goal(leveld[kk].state,GoalState)) {
final=leveld[kk].list;
leave=true;
break;
}
}
}
d = aa-stop;
}
if (leave){
cout<<"The solution is "<<endl;
display(root.state);
for (int i=0; i<a; i++){
for (int j=0; j<final.size();j++){
if (final[j] == levela[i].id){
display(levela[i].state);
}
}
}
for (int i=0; i<b; i++){
for (int j=0; j<final.size();j++){
if (final[j] == levelb[i].id){
display(levelb[i].state);
}
}
}
for (int i=0; i<c; i++){
for (int j=0; j<final.size();j++){
if (final[j] == levelc[i].id){
display(levelc[i].state);
}
}
}
for (int i=0; i<d; i++){
for (int j=0; j<final.size();j++){
if (final[j] == leveld[i].id){
display(leveld[i].state);
}
}
}
}
delete levela;
delete levelb;
delete levelc;
delete leveld;
system ("pause");
return 0;
}
-
September 7th, 2011, 03:13 PM
#2
Re: C++ vector length error at run time
Originally Posted by bloo
the code compiles, but when debugging there is an error
First thing you should know is that successful compilation means nothing when it comes to actually running the program. A successful compilation means the program is syntactically correct,. i.e. the C++ syntax is valid -- it doesn't determine if the program is logically correct or will run correctly.
Second, you say you're using vectors, but for the things you should be using vector for, you don't use it. Things like this:
Code:
levela = new node[aa];
//...
levelb = new node[bb];
//...
levelc = new node[cc];
//...
leveld = new node[dd];
delete levela;
delete levelb;
delete levelc;
delete leveld;
//..etc
Code like this is exactly what vector is supposed to replace. You then mishandle the pointers at the end, namely you use the wrong form of delete (you use "delete" when you should use "delete[]"). You also have a memory leak if levelb or levelc or leveld throw an exception on new, since you didn't deallocate the memory for the previous levels (you only do a return).
Also, I didn't even check if there is more mismanagement with these pointers.
The way you replace this with vector is simple:
Code:
std::vector<node> levela(aa);
//...
std::vector<node> levelb(bb);
//..
std::vector<node> levelc(cc);
//..
std::vector<node> leveld(dd);
etc..
If an exception is thrown, you now shouldn't call delete, as the vector will clean up the memory automatically when the function exits or returns for any reason whatsoever. IMO the number 1 reason to use vectors is for things like this, but you completely missed using them here.
Then you do this:
Code:
node::node() { list.reserve(10); }
//...
//reserve for final path
final.reserve(10);
Don't you mean "resize()"? The reserve() does not create valid entries in a vector. All it does is make sure there is preallocated memory up-front so that subsequent insertions in the vector take less time. The resize() is the function that actually creates entries in the vector.
I feel logically my code is correct and so i have not posted everything. Also it is a lot to read, but i have posted all the bits concerning the vectors.
More times then not, code that is not posted is the cause of the error. If you corrupt memory anywhere in your program, it can affect other parts of the code that you may think it won't affect.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; September 7th, 2011 at 03:17 PM.
-
September 7th, 2011, 03:34 PM
#3
Re: C++ vector length error at run time
thanks for the reply, firstly i did mention that i felt my code was logically correct and i do understand that compiling means syntax, that's why i stated that it compiled.
secondly as far as i know i was not trying to use vectors here:
Code:
levela = new node[aa];
//...
levelb = new node[bb];
//...
levelc = new node[cc];
//...
leveld = new node[dd];
delete levela;
delete levelb;
delete levelc;
delete leveld;
//..etc
here i'm trying to create arrays of objects because i'm building a tree, and cannot predetermine how many nodes will be needed at each stage. so i tried to automatically create them, as i mentioned before i'm doing a bfs search, so my idea was to add a vector to each node as they created and create them in the way a bfs would be performed in a tree, so i'm "creating and searching" at the same time. so each node in the tree will have a vector which will store the path to it.
as for the reserve()
Code:
node::node() { list.reserve(10); }
//...
//reserve for final path
final.reserve(10);
here i did mean to preallocate memory in an effort to solve the error i mentioned in my previous post. i will post my complete code now. forgive me if u still feel i should create the nodes with vectors, i have spent a good few days on this code and i think u may be misunderstanding the point of the entire code.
-
September 7th, 2011, 03:38 PM
#4
Re: C++ vector length error at run time
Paul was suggesting that you should use vectors there, since you're already using them in other places.
Using 'reserve' is fine, as long as you know how it works. For example, this is wrong, but will compile fine:
Code:
std::vector<int> myVec;
myVec.reserve(50);
myVec[48] = 42;
Perhaps you meant to use "resize"?
Viggy
-
September 7th, 2011, 03:45 PM
#5
Re: C++ vector length error at run time
header file:
Code:
#ifndef HEADER_H
#define HEADER_H
#include <vector>
using std::vector;
class node{
public:
int state[3][3];
int id;
char action;
vector<int> list;
node* parent;
node();
~node();
};
void zero_position(int [3][3], int&, int&);
void zero_state(int r, int c, char *moves);
void copy(int [3][3], int [3][3]);
void swap_tiles(int [3][3], char, int, int);
bool repeat_goal(int [3][3], int [3][3]);
void display(int [3][3]);
#endif
definitions:
Code:
#include "header.h"
#include <iostream>
node::node() { list.reserve(10); }
node::~node() { }
void zero_position(int ste[3][3], int &r, int &c){
//at this point we find the position of zero or the blank
for (int i = 0; i<3; i++) {
for (int j=0; j<3; j++){
if (ste[i][j] == 0){
r = i;
c = j;
}
}
}
}
void zero_state(int r, int c, char *moves){
switch (r){
case 1:
switch (c){
case 1: {
moves[0]='l';
moves[1]='u';
break;
}
case 2: {
moves[0]='r';
moves[1]='l';
moves[2]='u';
break;
}
case 3: {
moves[0]='r';
moves[1]='u';
break;
}
}
break;
case 2:
switch (c){
case 1: {
moves[0]='d';
moves[1]='l';
moves[2]='u';
break;
}
case 2: {
moves[0]='r';
moves[1]='l';
moves[2]='u';
moves[3]='d';
break;
}
case 3: {
moves[0]='r';
moves[1]='u';
moves[2]='d';
break;
}
}
break;
case 3:
switch (c){
case 1: {
moves[0]='d';
moves[1]='l';
break;
}
case 2: {
moves[0]='r';
moves[1]='l';
moves[3]='d';
break;
}
case 3: {
moves[0]='r';
moves[2]='d';
break;
}
}
break;
}
return;
}
void copy(int one[3][3], int two[3][3]){
for (int r = 0; r<3; r++) {
for (int c=0; c<3; c++){
one[r][c]=two[r][c];
}
}
}
void swap_tiles(int s[3][3], char mov, int x, int y){
int a;
switch (mov){
case 'u': {
a = x-1;
s[x][y]=s[a][y];
s[a][y]=0;
break;
}
case 'd': {
a = x+1;
s[x][y]=s[a][y];
s[a][y]=0;
break;
}
case 'l': {
a = y-1;
s[x][y]=s[x][a];
s[x][a]=0;
break;
}
case 'r': {
a = y+1;
s[x][y]=s[x][a];
s[x][a]=0;
break;
}
}
}
bool repeat_goal(int state[3][3], int other[3][3]){
int count=0;
for (int i = 0; i<3; i++) {
for (int j=0; j<3; j++){
if (state[i][j] == other[i][j]){
count++;
}
}
}
if (count == 9){ return true;}
else return false;
}
void display(int st[3][3]){
for (int i=0; i<3; i++){
std::cout<<st[i][0]<<" "<<st[i][1]<<" "<<st[i][2]<<std::endl;
}
}
main:
Code:
#include <stdio.h>
#include <iostream>
#include <string>
#include "header.h"
int choice;
int i,j,x,y,a,b,c,d,aa, children, start, stop, child;
int InState [3][3];
int GoalState [3][3];
bool leave = false;
char moves[4];
std::vector<int> final;
using namespace std;
int main(){
GoalState[0][0] = 1;
GoalState[0][1] = 2;
GoalState[0][2] = 3;
GoalState[1][0] = 8;
GoalState[1][1] = 0;
GoalState[1][2] = 4;
GoalState[2][0] = 7;
GoalState[2][1] = 6;
GoalState[2][2] = 5;
cout<<"Welcome to the 8-puzzle"<<endl;
cout<<"Our goal state is :"<<endl;
cout<<endl;
for (i=0; i<3; i++){
cout<<GoalState[i][0]<<" "<<GoalState[i][1]<<" "<<GoalState[i][2]<<endl;
}
cout<<"\nEnter Initial State one integer at a time:"<<endl;
cout<<"Please use integers 0 to 8 only where 0 represents the blank tile"<<endl;
for (i = 0; i<3; i++) {
for (j=0; j<3; j++){
cin>> InState[i][j];
if (InState[i][j] > 8) {
cout<<"number should be from 0 to 8. Re-enter"<<endl;
cin>> InState[i][j];}
}
}
//at this point we find the position of zero or the blank
for (i = 0; i<3; i++) {
for (j=0; j<3; j++){
if (InState[i][j] == 0){
x = i;
y = j;
}
}
}
cout<<"x "<< x <<"y "<< y <<endl;
cout<<"The initial state selected is"<<endl;
for (i=0; i<3; i++){
cout<<InState[i][0]<<" "<<InState[i][1]<<" "<<InState[i][2]<<endl;
}
//reserve for final path
final.reserve(10);
//define the root node
node root;
for (int i = 0; i<3; i++) {
for (int j=0; j<3; j++){
root.state[i][j] = InState[i][j];
}
}
root.id=0;
//start vector list to find path to goal
root.list.push_back(root.id);
//find available moves for root
zero_state(x,y,moves);
/*cout<<"Available moves:"<<endl;
for (i=0; i<sizeof(moves); i++){
cout<<moves[i]<<endl;
}*/
aa=sizeof(moves);
a = aa;
//generate number of children from root, using the number of available moves
node *levela;
try {
levela = new node[aa];
} catch (bad_alloc xa) {
cout<<"Allocation Failure\n";
return 1;
}
if (leave!=true){
//********************put this in a do while loop.... must continue until goal is found*******
//max depth?????
//for each child of root generate their children the same way
for (int i=0; i<aa; i++){
//fill each node with required information
levela[i].id = i+1;
//find available moves for each child
zero_position(levela[i].state,x,y);
zero_state(x,y,moves);
//define their parent
levela[i].parent=&root;
//define their states
copy(levela[i].state,root.state);
swap_tiles(levela[i].state,moves[i],x,y);
//define path to state
levela[i].list=root.list;
levela[i].list.push_back(levela[i].id);
// total number of children for all nodes at this level
children+=sizeof(moves);
//determine if goal state reached?
if (repeat_goal(levela[i].state,GoalState)) {
final=levela[i].list;
leave=true;
break;
}
}
}
//define children for each node
start=aa;
int bb=children;
node *levelb;
try {
levelb = new node[bb];
} catch (bad_alloc xa) {
cout<<"Allocation Failure\n";
return 1;
}
if (!leave){
children=0;
for (int j=0; j<start; j++){
//determine parent node moves
zero_position(levela[j].state,x,y);
zero_state(x,y,moves);
child=sizeof(moves);
aa+=child;
// total number of children for all nodes at this level
children+=sizeof(moves);
for (int jj=0; jj<child;jj++){
//fill each node with required information
levelb[jj].id = start+jj;
//define their parent
levelb[jj].parent=&levela[j];
//define their states
copy(levelb[jj].state,levela[j].state);
swap_tiles(levelb[jj].state,moves[jj],x,y);
//define path to state
levelb[jj].list=levela[j].list;
levelb[jj].list.push_back(levelb[jj].id);
//determine if goal state reached?
if (repeat_goal(levelb[jj].state,GoalState)) {
final=levelb[jj].list;
leave=true;
break;
}
}
}
b=aa-start;
}
//define children for each node
int cc=children;
node *levelc;
//levelc = new node[cc];
try {
levelc = new node[cc];
} catch (bad_alloc xa) {
cout<<"Allocation Failure\n";
return 1;
}
if (!leave){
stop=aa;
children=0;
for (int k=start; k<stop; k++){
//determine parent node moves
zero_position(levelb[k].state,x,y);
zero_state(x,y,moves);
child=sizeof(moves);
aa+=child;
// total number of children for all nodes at this level
children+=sizeof(moves);
for (int kk=0; kk<child;kk++){
//fill each node with required information
levelc[kk].id = stop+kk;
//define their parent
levelc[kk].parent=&levelb[k];
//define their states
copy(levelc[kk].state,levelb[k].state);
swap_tiles(levelc[kk].state,moves[kk],x,y);
//define path to state
levelc[kk].list=levelb[k].list;
levelc[kk].list.push_back(levelc[kk].id);
//determine if goal state reached?
if (repeat_goal(levelc[kk].state,GoalState)) {
final=levelc[kk].list;
leave=true;
break;
}
}
}
c = aa-stop;
}
//define children for each node
int dd=children;
node *leveld;
//leveld = new node[dd];
try {
leveld = new node[dd];
} catch (bad_alloc xa) {
cout<<"Allocation Failure\n";
return 1;
}
if (!leave){
start=stop;
stop=aa;
children=0;
for (int k=start; k<stop; k++){
//determine parent node moves
zero_position(levelc[k].state,x,y);
zero_state(x,y,moves);
child=sizeof(moves);
aa+=child;
// total number of children for all nodes at this level
children+=sizeof(moves);
for (int kk=0; kk<child;kk++){
//fill each node with required information
leveld[kk].id = stop+kk;
//define their parent
leveld[kk].parent=&levelc[k];
//define their states
copy(leveld[kk].state,levelc[k].state);
swap_tiles(leveld[kk].state,moves[kk],x,y);
//define path to state
leveld[kk].list=levelc[k].list;
leveld[kk].list.push_back(leveld[kk].id);
//determine if goal state reached?
if (repeat_goal(leveld[kk].state,GoalState)) {
final=leveld[kk].list;
leave=true;
break;
}
}
}
d = aa-stop;
}
if (leave){
cout<<"The solution is "<<endl;
display(root.state);
for (int i=0; i<a; i++){
for (int j=0; j<final.size();j++){
if (final[j] == levela[i].id){
display(levela[i].state);
}
}
}
for (int i=0; i<b; i++){
for (int j=0; j<final.size();j++){
if (final[j] == levelb[i].id){
display(levelb[i].state);
}
}
}
for (int i=0; i<c; i++){
for (int j=0; j<final.size();j++){
if (final[j] == levelc[i].id){
display(levelc[i].state);
}
}
}
for (int i=0; i<d; i++){
for (int j=0; j<final.size();j++){
if (final[j] == leveld[i].id){
display(leveld[i].state);
}
}
}
}
delete levela;
delete levelb;
delete levelc;
delete leveld;
system ("pause");
return 0;
}
-
September 7th, 2011, 03:53 PM
#6
Re: C++ vector length error at run time
Originally Posted by MrViggy
Paul was suggesting that you should use vectors there, since you're already using them in other places.
Using 'reserve' is fine, as long as you know how it works. For example, this is wrong, but will compile fine:
Code:
std::vector<int> myVec;
myVec.reserve(50);
myVec[48] = 42;
Perhaps you meant to use "resize"?
Viggy
okay, but i don't totally understand how to use the vector in the first place and as i mentioned previously the vector is giving me the runtime error.
i do not want to resize them, as i explain the error says that the vector is too long and that's why i wanted to preallocate memory to it, should i resize it?
please take a look at my entire code and let me know if it's possible to simply resolve the current error, i know it could be completely wrong. all help is appreciated.
if Paul could please explain how i would use this, as u can see i tried to do everything with very simple knowledge of c++
Code:
std::vector<node> levela(aa);
//...
std::vector<node> levelb(bb);
//..
std::vector<node> levelc(cc);
//..
std::vector<node> leveld(dd);
-
September 7th, 2011, 04:24 PM
#7
Re: C++ vector length error at run time
Originally Posted by bloo
okay, but i don't totally understand how to use the vector in the first place
A vector is designed to be a drop-in replacement for a dynamic array allocated with "new". That tells you 95% of what you need to know about vectors.
When you hit the runtime error, which line is indicated in your debugger?
-
September 7th, 2011, 04:44 PM
#8
Re: C++ vector length error at run time
Originally Posted by bloo
i do not want to resize them, as i explain the error says that the vector is too long
There is no such thing as an error saying a vector is "too long". If anything, the vector is too small, and you're attempting to index an invalid entry.
and that's why i wanted to preallocate memory to it, should i resize it?
Understand the difference between resize() and reserve(), and I mentioned this already in my first post.
The reserve() function does not create entries in the vector. Therefore this code:
Code:
std::vector<int> t;
t.reserve(10);
t[5] = 1; // access the sixth element. Error!!
will not work. The code above does not mean that the vector has 10 entries in it. It has zero entries, so accessing element 6, for example, is illegal and produce a runtime error for debug versions of Visual C++. This is probably the error you are referring to. The main use for reserve() is again, to preallocate memory so that subsequent calls to add items in the vector occur faster.
The resize() actually places 10 empty elements in the vector. So the above code will work if you replace reserve() with resize(). So, get rid of the reserve() and use resize() -- you want to access element x of a vector, that vector better have at least x+1 elements in it, and reserve() does not accomplish this -- resize() does.
I think you're confused as to what resize() does, because the name of the function is "resize". When you declare a vector, it is initially empty:
Code:
std::vector<int> v;
The vector v has no entries. Now what if you want it to have 10 entries, and you already declared it with 0 entries? You call resize().
Code:
std::vector<int> v;
//.. a bunch of code here, who cares
// now we want to make v have 10 elements
v.resize( 10 );
Understand now? resize(n) means "make my vector have n elements".
if Paul could please explain how i would use this, as u can see i tried to do everything with very simple knowledge of c++
A vector is a dynamic array -- you are trying to do dynamic arrays using the tricky and error-prone new[]/delete[]. So instead of using new[]/delete[] use vector, as that is exactly what it's designed to do. In addition, your code has a memory leak because of you mishandling new[]/delete[], so even if you didn't realize this in the beginning, we here are going to look at all the code you posted and comment on anything that is amiss.
As to how to use it, you use it exactly as I stated previously -- get rid of new[] and delete[] and use vector as a dynamic array of node.
Code:
std::vector<node> levela(aa);
//...
std::vector<node> levelb(bb);
//..
std::vector<node> levelc(cc);
//..
std::vector<node> leveld(dd);
That code is all you need, and you remove those lines that use new[]/delete[]. You also don't need those try/catches any more, and you don't need those delete's at the end of main(). In other words, your code will become smaller and safer using vector than when you were using new[]/delete[].
Regards,
Paul McKenzie
Last edited by Paul McKenzie; September 7th, 2011 at 04:51 PM.
-
September 7th, 2011, 05:55 PM
#9
Re: C++ vector length error at run time
Originally Posted by Paul McKenzie
There is no such thing as an error saying a vector is "too long".
Perhaps unless something (completely unrelated) has corrupted some data members private to the vector object, thereby making the vector appear larger than vector::max_size() and triggering some internal assertion.
According to a little experiment I made, in a VC++ 2010 debug build vector<node>::max_size() (where node is the OP's class with commented-out c'tor and d'tor) returns 63161283 (0x3C3C3C3), which is way less than numeric_limits<size_type>::max().
Just an idea...
For reference: Is there a maximum number a vector can take?
I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.
This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.
-
September 8th, 2011, 03:18 AM
#10
Re: C++ vector length error at run time
Originally Posted by Lindley
A vector is designed to be a drop-in replacement for a dynamic array allocated with "new". That tells you 95% of what you need to know about vectors.
When you hit the runtime error, which line is indicated in your debugger?
Hi lindley I have tried what Paul suggested... using resize instead of reserve and I still get the same run time error, however I will use his other suggestions now and try again.
The error I receive is: Unhandled exception at 0x77a915ee in 8puzzle.exe: Microsoft C++ exception: std::length_error at memory location 0x0045f0cc
I am using Visual Studio 2008, with the library update.
Originally Posted by Paul McKenzie
There is no such thing as an error saying a vector is "too long". If anything, the vector is too small, and you're attempting to index an invalid entry.
Understand the difference between resize() and reserve(), and I mentioned this already in my first post.
The reserve() function does not create entries in the vector. Therefore this code:
Code:
std::vector<int> t;
t.reserve(10);
t[5] = 1; // access the sixth element. Error!!
will not work. The code above does not mean that the vector has 10 entries in it. It has zero entries, so accessing element 6, for example, is illegal and produce a runtime error for debug versions of Visual C++. This is probably the error you are referring to. The main use for reserve() is again, to preallocate memory so that subsequent calls to add items in the vector occur faster.
The resize() actually places 10 empty elements in the vector. So the above code will work if you replace reserve() with resize(). So, get rid of the reserve() and use resize() -- you want to access element x of a vector, that vector better have at least x+1 elements in it, and reserve() does not accomplish this -- resize() does.
I think you're confused as to what resize() does, because the name of the function is "resize". When you declare a vector, it is initially empty:
Code:
std::vector<int> v;
The vector v has no entries. Now what if you want it to have 10 entries, and you already declared it with 0 entries? You call resize().
Code:
std::vector<int> v;
//.. a bunch of code here, who cares
// now we want to make v have 10 elements
v.resize( 10 );
Understand now? resize(n) means "make my vector have n elements".
A vector is a dynamic array -- you are trying to do dynamic arrays using the tricky and error-prone new[]/delete[]. So instead of using new[]/delete[] use vector, as that is exactly what it's designed to do. In addition, your code has a memory leak because of you mishandling new[]/delete[], so even if you didn't realize this in the beginning, we here are going to look at all the code you posted and comment on anything that is amiss.
I do understand now, thank you for that explanation. I have tried this and still get the error which I stated above. However I will continue to make the changes you suggested and I will post my results. Thank you!
-
September 8th, 2011, 03:20 AM
#11
Re: C++ vector length error at run time
Originally Posted by Lindley
A vector is designed to be a drop-in replacement for a dynamic array allocated with "new". That tells you 95% of what you need to know about vectors.
When you hit the runtime error, which line is indicated in your debugger?
oh I forgot to say that the debugger stops at a line in the vector file:
_THROW(length_error, "vector<T> too long");
-
September 8th, 2011, 03:52 AM
#12
Re: C++ vector length error at run time
Originally Posted by Paul McKenzie
As to how to use it, you use it exactly as I stated previously -- get rid of new[] and delete[] and use vector as a dynamic array of node.
Code:
std::vector<node> levela(aa);
//...
std::vector<node> levelb(bb);
//..
std::vector<node> levelc(cc);
//..
std::vector<node> leveld(dd);
That code is all you need, and you remove those lines that use new[]/delete[]. You also don't need those try/catches any more, and you don't need those delete's at the end of main(). In other words, your code will become smaller and safer using vector than when you were using new[]/delete[].
Regards,
Paul McKenzie
Hi Paul, I just attempted changing this code now. The previous error does not come up, but instead I have a new error: Debug Assertion Failed! Program: ...8puzzle.exe File: ....\include\vector Line: 779
Expression: vector subscript out of range
By using vectors here, is there anything else I need to change, I read a bit and I think the way you access the objects is the same, is that correct? What other changes do I need to suit using vectors here?
-
September 8th, 2011, 05:23 AM
#13
Re: C++ vector length error at run time
Originally Posted by bloo
Hi Paul, I just attempted changing this code now. The previous error does not come up, but instead I have a new error: Debug Assertion Failed! Program: ...8puzzle.exe File: ....\include\vector Line: 779
Expression: vector subscript out of range
That is much better. Now you are told exactly what you were doing wrong before, and probably the reason why you were crashing from the beginning.
When you were using new[]/delete[] and pointers, you were overwriting memory. The problem is that overwriting memory when using raw pointers does not usually reveal itself when you run the program. Instead, you corrupt other areas of the program thereby getting the messages that "vector too long".
Now that you've changed to vector from using pointers, it is obviously clear that you were accessing invalid memory, but this time you get the indication that you're accessing an invalid vector entry. That is also the advantage of using vector (at least in debug mode). Visual C++ checks if you're using operator[] illegally, and you are.
The error means that your vector has a maximum of x elements, and you're writing beyond element x-1 (elements start at 0 and go to x-1). This is simple to diagnose, but you have to debug your program as to why you're writing beyond the legal limits of your vector.
By using vectors here, is there anything else I need to change, I read a bit and I think the way you access the objects is the same, is that correct?
It is exactly the same.
What other changes do I need to suit using vectors here?
None. You need to debug your code, as your quote below isn't correct:
I feel logically my code is correct and so i have not posted everything
Obviously, your program isn't logically correct. Time to debug it.
Regards,
Paul McKenzie
-
September 8th, 2011, 06:21 AM
#14
Re: C++ vector length error at run time
Originally Posted by Paul McKenzie
Obviously, your program isn't logically correct. Time to debug it.
Regards,
Paul McKenzie
Thanks so much! will try to do that.
-
September 8th, 2011, 10:34 AM
#15
Re: C++ vector length error at run time
Originally Posted by bloo
oh I forgot to say that the debugger stops at a line in the vector file:
_THROW(length_error, "vector<T> too long");
Okay, now look further up the call stack and see which part of your code is triggering that. Also look at what the internals of the vector look like at that time.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|