My Layer class is:
Layer::Layer(int _nOutput, vector<double> **_iVector, vector<double> **_oVector, int _actFuncType)
{
....
}
Main Topics
Browse All TopicsHi Guys,
It is my turn to face some problem here... The followings is my C++ code and output:
#include <iostream>
#include <vector>
#include "Layer.h"
using namespace std;
int main(int argc, char *argv[])
{
vector<double> *iVec;
iVec = new vector<double>;
iVec->push_back(1.23);
iVec->push_back(2.34);
iVec->push_back(3.45);
iVec->push_back(4.56);
for (int i = 0; i < 3; ++i) {
if (i == 0) {
vector<Layer *> v_layer;
vector<double> *h_output1, *h_output2;
cout << "i == 0\n";
h_output1 = NULL;
v_layer.push_back(new Layer(5, &iVec, &h_output1, 1));
cout << (*v_layer.at(0)->iVector)-
h_output2 = NULL;
v_layer.push_back(new Layer(5, &iVec, &h_output2, 1));
cout << (*v_layer.at(0)->iVector)-
}
if (i == 1) {
vector<Layer *> v_layer;
vector<vector<double> *> h_output;
cout << "i == 1\n";
h_output.push_back(NULL);
v_layer.push_back(new Layer(5, &iVec, &h_output.back(), 1));
cout << (*v_layer.at(0)->iVector)-
h_output.push_back(NULL);
v_layer.push_back(new Layer(5, &iVec, &h_output.back(), 1));
cout << (*v_layer.at(0)->iVector)-
}
if (i == 2) {
vector<Layer *> v_layer;
vector<double> *h_output[2];
cout << "i == 2\n";
h_output[0] = NULL;
v_layer.push_back(new Layer(5, &iVec, &h_output[0], 1));
cout << (*v_layer.at(0)->iVector)-
h_output[1] = NULL;
v_layer.push_back(new Layer(5, &iVec, &h_output[1], 1));
cout << (*v_layer.at(0)->iVector)-
}
}
return EXIT_SUCCESS;
}
~.~.~.~.~.~.~.~.~.~.~.~.~.
[slyong@localhost vault]$ ./a.out
i == 0
4:5
4:5
i == 1
4:5
4:0
i == 2
4:5
4:5
My problem is that when i == 0, I use variables of "pointer to a vector containing doubles", vector<double> *. When i == 1, I use a vector of "pointer to a vector containing doubles", vector<vector<double> *> and when i==3, I use an array of "pointer to a vector containing doubles". However when I use vector<vector<double> *> the result is different.
I have been scratching my head for quite a while now.. help?
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
well.. hope this is not too long to paste here:
// Layer.h
#include <vector>
using namespace std;
#ifndef _LAYER_H_
#define _LAYER_H_
class Layer
{
public:
int nInput, nOutput;
double **weights;
vector<double> **iVector, **oVector;
double (*actFuncPtr)(double);
Layer(int, vector<double> **, vector<double> **, int =0);
~Layer();
static double sigmoidalActFunc(double);
static double emptyActFunc(double);
void run(int =1);
};
#endif /*_LAYER_H_*/
// Layer.cpp
#include <iostream>
#include <math.h>
#include "Layer.h"
using namespace std;
Layer::Layer(int _nOutput, vector<double> **_iVector, vector<double> **_oVector, int _actFuncType)
{
if (*_oVector != NULL && _nOutput != (int)(*_oVector)->size()) {
cerr << "The size of output vector mismatch\n";
exit(EXIT_FAILURE);
}
nInput = (*_iVector)->size();
nOutput = _nOutput;
iVector = _iVector;
oVector = _oVector;
switch (_actFuncType) {
case 0 :
actFuncPtr = &sigmoidalActFunc;
break;
case 1 :
actFuncPtr = &emptyActFunc;
break;
default:
actFuncPtr = &emptyActFunc;
break;
}
if (*oVector == NULL) {
*oVector = new vector<double>(nOutput, 0);
_oVector = oVector;
}
double *tWeights = (double *) malloc(nInput * nOutput * sizeof(double));
int i;
if (tWeights == NULL) {
cerr << "Unable to allocate memory\n";
exit(EXIT_FAILURE);
}
for (i = 0; i < nInput * nOutput; ++i) {
*(tWeights + i) = (double)rand()/RAND_MAX;
}
weights = (double **) malloc(nInput * sizeof(double *));
if (weights == NULL) {
cerr << "Unable to allocate memory\n";
exit(EXIT_FAILURE);
}
for (i = 0; i < nInput; ++i) {
weights[i] = tWeights + (i * nOutput);
}
}
Layer::~Layer()
{
free(*weights);
}
double Layer::sigmoidalActFunc(do
{
return (double)1/(1+exp(-_input))
}
double Layer::emptyActFunc(double
{
return _input;
}
void Layer::run(int _step)
{
int step, i, j;
for (step = 0; step < _step; ++step) {
for (i = 0; i < nOutput; ++i) {
for (j = 0; j < nInput; ++j) {
(*oVector)->at(i) += (*iVector)->at(j) * weights[j][i];
}
(*oVector)->at(i) = actFuncPtr((*oVector)->at(
}
}
}
>>>> If you don't see the difference, let me know...
Actually, I can see the difference but don't see the improvement ...
_oVector is a pointer to pointer argument that was returned to the caller. Hence, it can get a new assignment ...
I don't know why the class uses pointer to pointer arguments cause that is a C technique. In C++ references should be used:
Layer::Layer(int _nOutput, vector<double>*& _iVector, vector<double>*& _oVector, int _actFuncType)
Much better would be to not using pointers at all but only passing an input vector by reference:
class Layer
{
private:
...
vector<double>& iVector; // make a reference if you always get an input vector when cconstructed
// vector<double> iVector; // else make a copy if you need the input data after construction
// drop the member if you need the input vector in the contructor only
vector<double> oVector;
public:
Layer(int _nOutput, vector<double>& _iVector, int _actFuncType);
};
Layer::Layer(int _nOutput, vector<double>& _iVector, int _actFuncType)
: oVector(nOutput, 0), iVector(_iVector)
{
....
}
If you need the output vector somewhere else, you should add an appropriate get function as a member of class Layer:
const vector<double>& Layer::getOutput() { return oVector; }
Two more remarks:
- The '_' prefix normally is used for member data. You shouldn't it use for arguments.
- You are using mallloc and free. In C++ you should use 'new' and 'delete' instead.
Regards, Alex
Well, that correction would have been necessary for it to work if everything else was OK. But I think I see now why it isn't and why I didn't get the problem!
What are you doing here:
1. Pushing a value onto a vector (h_output).
2. Storing the address of an element of this vector (oVector in Layer is the address of h_output[0] at this point).
3. Pushing another value onto h_output. Now this invalidates any pointers stored to existing elements of the vector, since the whole vector might be reallocated in memory! If this happens (which it seems to do when you try, but I was lucky enough to get away with it), your oVector for the first Layer will not be valid anymore and you might get anything trying to access it.
So, what do you do? There are lot of ways to clean up this code considerably, but the smallest change might be declaring:
vector<vector<double> *> h_output(2);
That way you would avoid the reallocation in _practice_, but I'm not sure it is _guaranteed_ to work in the standards.
I would recommend rewriting the whole thing, e.g. by storing a reference to h_output as static in Layer and then an offset instead of a pointer to get the element you want.
Hi guys,
I use C most of the time hence I am not really good in C++ code/practises. I know that the class Layer does not practise good C++. However, the problem that I am facing is that from the main(), i==0, i==1 and i==2 behaved differently. khun explained that the h_output would be reallocated in memory once a new element is pushed into it, that explain why I am getting the different, since arrays and static variables are not move around memory.
The suggestion that using vector<vector<double> *> h_output(2); works but when I need to grow the h_output, I will face the same problem (I need the capability for doing some Back Prop Thru Time - keeping all the time layers).
Anyway, I understand the problem now and I think that Alex has some good suggestion that I should really try to recode my class.
Thanks for help..
Thanks for the points and yes, you should definitely recode! Note that in Alex's code you are duplicating the oVector, that's the difference that should make it work, not using reference instead of pointer. Using an index into the real vector could spare you the duplication, but that's a design matter with many aspects, which I won't discuss now. Just make sure you don't use something like:
vector<double>*& oVector;
instead, since that will give you the same problems as you have now.
That said, I have to give you right on another topic, Alex, although it is a little beside the point now. I see you are right, there was no improvement! I got carried away because the last line of:
if (*oVector == NULL) {
*oVector = new vector<double>(nOutput, 0);
_oVector = oVector;
}
doesn't make any sense. And forgot to realize, that with the:
oVector = _oVector;
further up, the code would have worked if it hadn't been for the other problems...
Business Accounts
Answer for Membership
by: khunPosted on 2005-10-12 at 01:54:17ID: 15067125
back returns a "reference to last element of vector", shouldn't you use:
v_layer.push_back(new Layer(5, &iVec, h_output.back(), 1));
instead?