Home > Software design >  Returning a 2D Vector from a function through a pointer to a different class
Returning a 2D Vector from a function through a pointer to a different class

Time:02-01

I know this question sounds familiar. There are many similar questions. I have gone through the list of suggested duplicate questions. I'm a seeking a much more streamline approach.

I am making a game that spawns animated 'pixel art' cats and other animals.... These are your typical in-game pets, which get spawned next to the player.

I am using the Meow class to hold sprite data for the cat's in-game object. I'm sending that data (through a pointer ->) to favorite_pet::initialize(), which loads the sprite data for the pet.

Unfortunately, using the debug features are of no help. Everything checks out until the following line...

vec_cat_data_input_2D = point_kitty->cat_data(vec_cat_sprite_ids);

...then BOOM! The system crashes and all of the cats stop meowing.

I suspect sending that 2D vector though a function call in a pointer to a class is the problem.

However, if I do this same thing with a 1D vector and a variable, everything is fine.

vec_cat_data_input_1D = point_kitty->cat_data(variable_cat_sprite_ids); // Is okay!

The 2D vector being received could be of any size (rows or columns). This setup is going to be the prototype for a group of classes that are not going to be children of the class holding the data. The pets are children of physics and api image ctrl features. Thus, I don't want that data being stored in the objects that ctrl the in-game sprites.

With that same idea in mind, I am not trying to superglue a dozen pointers together (two per class) so I can predict (n,m) ahead of time. Likewise, I realize that I could be using pointer functions or void functions with pointer vectors to do the processing and data tranfer. I'm trying to avoid any unecessary memory allocations, pointer cleanup or global data. I am hoping for something more memory effient.

However, I do use ClassObject* point_blah; to call functions rather than calling objects directly.

#include "favorite_pet.h"
void main()
{
    favorite_pet NewPet;
    NewPet.initialize();
}

// ------------------------------------------------------------------------------------------------------

#pragma once
// favorite_pet.h
#include "meow.h"
class favorite_pet
{
private:

    Meow* point_kitty;

    // do not want to create two more pointers just so I can predict what the (n,m) sizes might be...
    std::vector<std::vector<float>> vec_cat_data_input_2D;

public:
    // constructor
    favorite_pet();

    void initialize();

    std::vector<int> vec_cat_sprite_ids;
};

// ------------------------------------------------------------------------------------------------------

#include "favorite_pet.h"

// default constructor
favorite_pet::favorite_pet()
{
    point_kitty = new Meow();
}

void favorite_pet::initialize()
{
    // some rando value
    vec_cat_sprite_ids.push_back(0);
    vec_cat_sprite_ids.push_back(1);
    vec_cat_sprite_ids.push_back(2);

    // grab data from other class, that is not a parent or a friend
    vec_cat_data_input_2D = point_kitty->cat_data(vec_cat_sprite_ids);

    // blah blah blah
    // stuff and jumk

    delete point_kitty;
    point_kitty = NULL;
}

// ------------------------------------------------------------------------------------------------------

#pragma once
// meow.h
#include <vector>

class Meow
{
private:

public:
    // constructor
    Meow();

    std::vector<std::vector<float>> cat_data(std::vector<int>&);

    std::vector<std::vector<float>> vector_cat
    {
        //
        { 0, 1, 2, 3, 4},
        { 5, 6, 7, 8, 9},
        { 10, 11, 12, 13, 14},
        { 15, 16, 17, 18, 19}
    };

    std::vector<std::vector<float>> vec_cat_sprite_data_output_2D;
};

// ------------------------------------------------------------------------------------------------------

#include "meow.h"
#include <vector>

Meow::Meow()
{

}

std::vector<std::vector<float>> Meow::cat_data(std::vector<int>& vec_id_list)
{
    for (int var_incoming_list = 0; var_incoming_list < vec_id_list.size(); var_incoming_list  )
    {
        vec_cat_sprite_data_output_2D.emplace_back();
        for (int var_output = 0; var_output < vec_id_list.size(); var_output  )
        {
            vec_cat_sprite_data_output_2D[var_output].push_back(vector_cat[vec_id_list[var_incoming_list]][var_output]);
        }
    }
    return vec_cat_sprite_data_output_2D;
}

CodePudding user response:

This is probably your culprit.

vec_cat_sprite_data_output_2D.emplace_back();
for (int var_output = 0; var_output < vec_id_list.size(); var_output  ){
vec_cat_sprite_data_output_2D[var_output].push_back(vector_cat[vec_id_list[var_incoming_list]][var_output]);
}

You create an empty vector in this first line, and in the third line you assume that vec_cat_sprite_data_output_2D[var_output] exists. Maybe you meant to write to the just newly created vector, in which case vec_cat_sprite_data_output_2D.back() would do the trick.

Also, you might want to consider using ranged for loops when looping over std containers, i.e.

for (int id_in : vec_id_list) {
  vec_cat_sprite_data_output_2D.emplace_back();
  for(int id_out = 0; id_out < vec_id_list.size(); id_out  ) {
    vec_cat_sprite_data_output_2D.back().push_back(vector_cat[id_in][id_out]);
  }
}

Maybe it wasn't your intention to create an new vector for each input id, in which case you should emplace_back a vector of a certain size and write to that one.

CodePudding user response:

Sorry guys and girls...

this should have been...

std::vector<std::vector<float>> Meow::cat_data(std::vector<int>& vec_id_list)
{
    for (int var_incoming_list = 0; var_incoming_list < vec_id_list.size(); var_incoming_list  )
    {
        vec_cat_sprite_data_output_2D.emplace_back();
        for (int var_output = 0; var_output < vec_id_list.size(); var_output  )
        {
            vec_cat_sprite_data_output_2D[var_output].push_back(vector_cat[vec_id_list[var_incoming_list]][var_output]);
        }
    }
    return vec_cat_sprite_data_output_2D;
}

this...

std::vector<std::vector<float>> Meow::cat_data(std::vector<int>& vec_id_list)
{
    for (int var_incoming_list = 0; var_incoming_list < vec_id_list.size(); var_incoming_list  )
    {
        vec_cat_sprite_data_output_2D.emplace_back();
        for (int var_output = 0; var_output < vec_id_list.size(); var_output  )
        {
            vec_cat_sprite_data_output_2D[var_incoming_list].push_back(vector_cat[vec_id_list[var_incoming_list]][var_output]);
        }
    }
    return vec_cat_sprite_data_output_2D;
}
  • Related