-2

I'm using CodeBlocks for C++ and it's probably a compiler issue. I am learning using vector pointer and tried to create function that return vector pointer. Below is my code. It has compiled and executed before without using pointer. Now I try to have a function that returns pointer, but somehow it doesn't work and I couldn't figure out the errors. Please help.

error:

main.cpp|8|undefined reference to `RandomNum::RandomNum(int, int, int, int)
main.cpp|9|undefined reference to `RandomNum::getVecPointer()

main.cpp

#include <iostream>
#include "RandomNum.h"

using namespace std;

int main()
{
    RandomNum rand(5, 5, 100, 1000);  <----error 
    vector<float>* p = rand.getVecPointer();
    cout << (*p)[0] << endl;

    return 0;
}

RandomNum.h

#include <vector>

#ifndef RANDOMNUM_H
#define RANDOMNUM_H

class RandomNum
    {
private:

    int M, x, y, z; //M is the number of cells
    std::vector <float> aVector;

public:
    //constructor
    RandomNum(int, int, int, int);

    //generate random float between 0 and 1;
    float unif();

    //build a vector of random points
    std::vector<float>* getVecPointer();
};
#endif

RandomNum.cpp

#include "RandomNum.h"
#include <cmath>  //for trunc()

RandomNum::RandomNum( int MM,int xx, int yy, int zz )
{
    //x, y, z are seeds, M is the number of random numbers to be    generated [0,1]
    M = MM;
    x = xx;
    y = yy;
    z = zz;
}

float RandomNum::unif()
{
    float tmp;

    ...

    return(tmp - trunc(tmp));
}

std::vector<float>* RandomNum::getVecPointer()
{
    int i ;
    for (i = 0 ; i < M; i++)
    {
        float x = unif();
        aVector.push_back(x);
    }
    return &aVector;
}
MLAC
  • 129
  • 2
  • 10
  • 2
    First of all, you *do* build with the `RandomNum.cpp` file, and link with the object file it generates? Secondly, the "normal" thing is to return a *reference* instead of a pointer, makes it easier to use e.g. the indexing operator. Thirdly, the name `getVecPointer` is a little misleading, the function doesn't *only* return a pointer to the vector, it also fills it with data. – Some programmer dude Oct 28 '15 at 06:12
  • More specifically, something like `g++ -c RandomNum.cpp && g++ -o main main.cpp RandomNum.o` (adjust for compiler/platform). – Tony Delroy Oct 28 '15 at 06:14
  • Please share the details of how you build this code. Most probably there is a linking error in your implementation. – Validus Oculus Oct 28 '15 at 06:14
  • I build the program with CodeBlocks 13.11 – MLAC Oct 28 '15 at 06:16
  • @Tony How can I adjust it? – MLAC Oct 28 '15 at 06:17
  • 2
    Possible duplicate of [code::blocks - how to compile multiple file projects](http://stackoverflow.com/questions/5971206/codeblocks-how-to-compile-multiple-file-projects) – smac89 Oct 28 '15 at 06:38
  • @Smac89 I only work on one project now. – MLAC Oct 28 '15 at 06:40
  • @MLAC: I've no idea - I don't use CodeBlocks - try reading the CodeBlocks documentation or FAQ. – Tony Delroy Oct 28 '15 at 06:45
  • @joachim a function returning a pointer is quite common. http://www.functionx.com/cpp/examples/returnpointer.htm – MLAC Oct 28 '15 at 06:54
  • Thanks for everyone's comments here. I adjusted the compiler setting and it works just fine now. And the function returning a pointer also works. – MLAC Oct 28 '15 at 06:58

2 Answers2

1

I'm unable to reproduce your problem. I downloaded your files and I created a Makefile:

OLIST += rand.o RandomNum.o

CFLAGS += -Wall -Werror

all: rand

%.o: %.cpp
    c++ $(CFLAGS) -c $<

rand: $(OLIST)
    c++ -o rand $(OLIST)

clean:
    rm -f *.o rand

Here's the output of the make:

c++ -Wall -Werror -c rand.cpp
c++ -Wall -Werror -c RandomNum.cpp
c++ -o rand rand.o RandomNum.o

Note that because you were having a compile issue, I nop'ed the trunc call so things would be simpler (i.e. it wasn't germane to the problem you were having). Also, I renamed main.cpp to rand.cpp [again, should make no difference]

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
  • Thanks. I adjusted the setting of the compiler and now the program executes as I've expected. The experiment function I made returning a pointer works just fine. – MLAC Oct 28 '15 at 07:04
0

If you use the public member vector::at function, which returns an element at position i in the vector, your code will work...

int main()
{
    RandomNum rand(5, 5, 100, 1000); // <----error  
    vector<float>* p = rand.getVecPointer();
    for (int i = 0; i < p->size(); i++) {
        cout << (p)->at(i);
    }

    return 0;
}

Although this is a valid program, there are few reasons to use pointer to vector. Vectors are built to use Resource Acquisition Is Initialization (RAII), a method of managing their own memory. When you use pointer to vector, you defeat the purpose of RAII. You may have to deal with memory allocation/cleanup, null pointers, etc, which is what RAII is supposed to spare you from.

Your getVecPointer() function can return the vector::data public member function which returns a pointer to the first element in the array used internally by the vector...

int* p = myvector.data();
dspfnder
  • 1,135
  • 1
  • 8
  • 13