CodeBlocks compiler issue, C++ - c++

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;
}

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]

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();

Related

g++ error in compiling while using std::string[5] as a type in std::map<>

I am fairly new to c++, I was making a encryptor to imrpove my c++, at first I kept my Cryptographer class in cryptographer.hpp and then added function body in cryptographer.cpp and then included cryptographer.hpp in main.cpp it gave me a compiler error, so I just pasted the code in main.cpp like this
#include <iostream>
#include <map>
class Cryptographer{
public:
int n_factor;
std::string text;
Cryptographer(std::string user_arg, int user_n_factor);
struct cryptographer
{
std::string encrypted_text;
std::string generated_key="";
};
cryptographer crypted_text;
void generate_key();
void encrypt();
void decrypt();
std::string get_key();
std::string get_text();
};
using key_map = std::map<char, std::string[5]>;
void Cryptographer::generate_key(){
for (int _ = 0; _ < 5; _++){
crypted_text.generated_key += rand() % 26 + 65;
}
}
void Cryptographer::encrypt(){
generate_key();
key_map keyHashMap;
for (auto key_letter: crypted_text.generated_key){
int key_letter_int = (int) key_letter;
std::string key_letter_arr[5];
int memory_number = key_letter_int;
for (int index=0; index < 5; index++){
if (memory_number+n_factor > 91){
memory_number = 65;
}else{
key_letter_arr[5] = std::string(1, char (memory_number + n_factor));
memory_number += n_factor;
}
}
keyHashMap.emplace(key_letter, key_letter_arr);
}
for(int index=0; index<text.size(); index++){
int key = index %4;
int key_patter = rand()% 4;
int checking_index = 0;
for (auto &elem: keyHashMap){
if (checking_index == key){
std::cout << elem.second[1];
}
}
}
crypted_text.encrypted_text = "test";
}
Cryptographer::Cryptographer(std::string user_arg, int user_n_factor):
text(user_arg), n_factor(user_n_factor)
{}
int main(){
Cryptographer crypter("hello guys", 3);
crypter.encrypt();
std::cout << crypter.get_text();
return 0;
}
and ran this in my terminal
g++ main.cpp -o test
and it popped this large error
https://hastebin.com/cibeyanoro.cpp
I am on ubuntu 20.04, I also tried removing and reinstalling latest version of g++ but the same error pops up.
g++ error in compiling while using std::string[5] as a type in std::map<>
Arrays cannot be stored as elements of std::map. You can store classes though, and arrays can be members of a class. The standard library provides a template for such array wrapper. It's called std::array. You can use that as the element of the map instead.
Sidenote: std::map isn't the only standard container with such limitation. std::array is the only standard container that can itself contain arrays as elements.

Program crashing with C++ DLL using OpenMP

I have a program using OpenMP on C++ and I need it to port into Dll so I can call it from Python. It returns an array of double values, which calculated using a lot of for loops with openmp pragma. I was doubtful if it is going to work, so I started from a little test program that calculates Pi value in a loop with different precision values, then I would measure performance and ensure that OpenMP works properly that way. Plain (w/o Omp) implementation works fine from Python and C++, however Omp variant gives a runtime error in Python (exception: access violation writing 0x000000000000A6C8) and crashes without an error in C++. Also Omp variant works fine if it is not a Dll and just a regular executable. The Dll is made with a makefile. App that uses the Dll built into an executable with g++ with no flags (source code is in UnitMain.cpp). All the relevant code and a Makefile below (I didn't include some files and functions for brevity).
UPD: I tried Microsoft compiler and it works, also I tested a linux dynamic library on WSL/g++ and it also works. Looks like it is Windows gcc specific, I'll try another version of gcc (btw my current version is this):
Thread model: posix gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
UnitFunctions.cpp
#include "UnitFunctions.h"
#include <omp.h>
#include <stdio.h>
#include <string.h>
typedef long long int64_t;
double pi(int64_t n) {
double sum = 0.0;
int64_t sign = 1;
for (int64_t i = 0; i < n; ++i) {
sum += sign/(2.0*i+1.0);
sign *= -1;
}
return 4.0*sum;
}
void calcPiOmp(double* arr, int N) {
int64_t base = 10e5;
#pragma omp parallel for
for(int i = 0; i < N; ++i) {
arr[i] = pi(base+i);
}
}
UnitMain.cpp
#include <windows.h>
#include <iostream>
using namespace std;
struct DllHandle
{
DllHandle(const char * const filename)
: h(LoadLibrary(filename)) {}
~DllHandle() { if (h) FreeLibrary(h); }
const HINSTANCE Get() const { return h; }
private:
HINSTANCE h;
};
int main()
{
const DllHandle h("Functions.DLL");
if (!h.Get())
{
MessageBox(0,"Could not load DLL","UnitCallDll",MB_OK);
return 1;
}
typedef const void (*calcPiOmp_t) (double*, int);
const auto calcPiOmp = reinterpret_cast<calcPiOmp_t>(GetProcAddress(h.Get(), "calcPiOmp"));
double arr[80];
calcPiOmp(arr, 80);
cout << arr[0] << endl;
return 0;
}
Makefile
all: UnitEntryPoint.o UnitFunctions.o
g++ -m64 -fopenmp -s -o Functions.dll UnitEntryPoint.o UnitFunctions.o
UnitEntryPoint.o: UnitEntryPoint.cpp
g++ -m64 -fopenmp -c UnitEntryPoint.cpp
UnitFunctions.o: UnitFunctions.cpp
g++ -m64 -fopenmp -c UnitFunctions.cpp
A Python script
import numpy as np
import ctypes as ct
cpp_fun = ct.CDLL('./Functions.dll')
cpp_fun.calcPiNaive.argtypes = [np.ctypeslib.ndpointer(), ct.c_int]
cpp_fun.calcPiOmp.argtypes = [np.ctypeslib.ndpointer(), ct.c_int]
arrOmp = np.zeros(N).astype('float64')
cpp_fun.calcPiOmp(arrOmp, N)

Undefined reference to 'HashTable::HashTable()'

I'm working on a testing program for a lab and I keep getting the error
[jereminp#bondi hw3]$ make insert_test
g++ -O3 -g -o insert_test.o -c insert_test.cc
g++ -O3 -g -o insert_test insert_test.o
insert_test.o: In function `main':
/users/ugrad/2018/fall/jereminp/114/hw3/hw3/insert_test.cc:17: undefined reference to `HashTable::HashTable()'
/users/ugrad/2018/fall/jereminp/114/hw3/hw3/insert_test.cc:24: undefined reference to `HashTable::insert(int)'
/users/ugrad/2018/fall/jereminp/114/hw3/hw3/insert_test.cc:32: undefined reference to `HashTable::insert(int)'
collect2: ld returned 1 exit status
make: *** [insert_test] Error 1
I'm fairly certain I have the logic, but I can't get past this error and I feel like I'm missing something simple. Here's the parts of the code in question.
Makefile
CC = g++
CFLAGS =
COPTFLAGS = -O3 -g
insert_test: insert_test.o
$(CC) $(COPTFLAGS) -o $# $^
insert_test.cc
#include "HashTable.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
class HashTable;
int main(int argc, char* argv[])
{
//checks .5 and .9 1x
int numRuns = 0;
int numProbes = 0;
int a=0;
HashTable h;
HashTable.hh
#ifndef HASHTABLE_H
#define HASHTABLE_H
class HashTable
{
public:
HashTable();
/* implement copy constructor, assignment, destructor if needed */
int hashfnc(int key);
int insert (int value);
/* insert the input value and return the number of probes
* return -1 if the table is full and insert fails */
bool find (int value, int& nProbes);
/* Search for the input value in table
* Return true if the search is successful, otherwise false
* Save # probes in 'nProbes' */
// getters
int capacity() { return nSlot; }
int size() { return nElem; }
double load_factor() { return load; }
int getSearchProbes() { return probesSearch; }
private:
/* declare your data */
double load; // track the load factor of table
int nSlot; // # slots i.e. max # elements can hold
int nElem; // current # elements in table
int arr[];
int probesSearch;
};
#endif
HashTable.cc
#include "HashTable.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
class HashTable
{
public:
HashTable()
{
load = 0;
nSlot = 300;//nSlot is changable in order to optimize
nElem = 0;
arr = new int[nSlot];
probesSearch=0;
for(int i = 0;i<nSlot;i++)
{
arr[i] = NULL;
}
}
Some of the things I've tried are adding any and all includes I could think of, changing the last line shown in insert_test.cc to "HashTable h = new HashTable();"(where I got a different error), adding namespace std to the header. I feel like it should be a quick fix but at the same time I can't find the solution anywhere. Plz send help

Exclude C++ standard library function calls from gprof output

I am using the C++ standard library in some C++ code and this makefile:
CC=g++
CXXFLAGS=-Wall -Werror -ggdb3 -std=c++11 -pedantic $(OTHERFLAGS)
cpp_sort: cpp_sort.o
g++ -o $# $(CXXFLAGS) $^
clean:
rm -rf *.o cpp_sort *~
The source code:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void get_input(vector<int>& items, int size) {
for (int i = 0; i < size; ++i) {
int element;
cin >> element;
items.push_back(element);
}
}
void cpp_sort(vector<int>& items) {
sort(items.begin(), items.end());
}
void print_array(vector<int>& items) {
for (auto& item : items) {
cout << item << ' ';
}
cout << endl;
}
int main() {
int size;
cin >> size;
vector<int> items;
items.reserve(size);
get_input(items, size);
cpp_sort(items);
print_array(items);
}
I call make like this:
make OTHERFLAGS=-pg
run the program (where large.txt is a long list of integers):
./cpp_sort <large.txt
and view the profiling information:
grof ./cpp_sort
Which is fine and it does work, but the calling of my functions is obscured by all the C++ standard library function calls. Is there a way to exclude the standard library internal function calls?

Why is my program giving a totally different output when I compile with mingw as compared to g++

So when i compile this code (using the mersenne twister found here: http://www-personal.umich.edu/~wagnerr/MersenneTwister.html ):
#include <iostream>
#include <cmath>
#include "mtrand.h"
using namespace std;
double pythag(double x, double y) {
double derp=0;
derp=(x*x)+(y*y);
derp=sqrt(derp);
}
int main() {
double x=0;
double y=0;
double pi=0;
double hold1=0;
double hold2=0;
double hits=0;
MTRand mt;
mt.seed();
// cout.precision(10);
for(long i=1; i<=100000000000l; i++) {
x=abs(mt.rand());
y=abs(mt.rand());
if(pythag(x,y)<=1) {
hits++;
}
if(i%100000l==0) {
pi=(4*hits)/i;
cout << "\r" << i << " " << pi ;
}
}
cout <<"\n";
return 42;
}
Using g++ ("g++ pi.cc -o pi")
And run the resulting application, I get the output i wanted, a running tally of pi calculated using the Monte Carlo method.
But, when i compile with mingw g++ ("i686-pc-mingw32-g++ -static-libstdc++ -static-libgcc pi.cc -o pi.exe")
I always get a running tally of 0.
Any help is greatly appreciated.
Perhaps it's because you omitted the return statement:
double pythag(double x, double y) {
double derp=0;
derp=(x*x)+(y*y);
derp=sqrt(derp);
// You're missing this!!!
return derp;
}
I'd be surprised that you didn't get any warnings or errors on this.
pythag() does not return anything, as Loki is trying to say without telling you the exact answer. That means the return value is not specified.
Why do you return 42 in main()?! 8-)