Unable to access a Private Array - arrays

I'm having difficulty accessing an array of strings. It is declared as a private array and filled in the constructor for the class. I have a Get function defined. The problem is when I call this function at compile time I get an error that I cannot access private member declared in class. I'm just getting back into coding just for the yuks, as such I'm at a stage pre-pointers and pre-vectors so I'm trying to avoid situations that would force their use.
Words.h
#pragma once
#include <string>
#include <iostream>
#include <array>
class Words {
Words();
public:
std::string GetNewWord(int);
private:
std::string WordList[23] = {};
};
Words.cpp - The Array is completely filled but shortened here
#include "Words.h"
Words::Words(){
WordList[0] = "omega";
WordList[1] = "minors";
WordList[2] = "stigma";
WordList[3] = "glamor";
WordList[4] = "savior";
WordList[5] = "disarm";
WordList[6] = "isogram";
.
.
.
;
}
std::string Words::GetNewWord(int choice)
{
return WordList[choice];
}
main.cpp - contains an infinite loop so i could quickly test if the array was populated
#include <iostream>
#include <string>
#include "Words.h"
Words word;
int main() {
do {
std::cout << "choice: ";
int choice;
std::cin >> choice;
std::cout << "\n" << word.GetNewWord(choice) << "\n";
} while (true);
return 0;
}

The constructor is private, as all members of a class are by default. Simply move it to the public section.

Related

LLVM Pass to insert an external function call to LLVM bitcode

I am writing an LLVM pass to instrument a C source program. I want to insert a function call before each branch instruction which calls an external function like this :
void print(int x){
printf("x = %d\n", x);
return;
}
I want to link this external function to C source code using llvm-link tool and then instrument the code using opt tool.
Ths pass that I have implemented is like this:
#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/IRBuilder.h"
#include <vector>
using namespace llvm;
namespace{
struct ir_instrumentation : public ModulePass{
static char ID;
Function *monitor;
ir_instrumentation() : ModulePass(ID) {}
virtual bool runOnModule(Module &M)
{
std::vector<Type *> args;
args.push_back(Type::getInt32Ty(M.getContext()));
ArrayRef<Type*> argsRef(args);
FunctionType *FT = FunctionType::get(Type::getVoidTy(M.getContext()), args, false);
Constant* myFunc = M.getOrInsertFunction("print", FT, NULL);
minitor = cast<Function>(myFunc);
for(Module::iterator F = M.begin(), E = M.end(); F!= E; ++F)
{
for(Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
{
for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI)
{
if(isa<BranchInst>(&(*BI)) )
{
errs() << "found a branch instruction!\n";
ArrayRef< Value* > arguments(ConstantInt::get(Type::getInt32Ty(M.getContext()), 5, true));
Instruction *newInst = CallInst::Create(monitor, arguments, "");
BB->getInstList().insert(BI, newInst);
errs() << "Inserted the function!\n";
}
}
}
}
return true;
}
};
char ir_instrumentation::ID = 0;
static RegisterPass<ir_instrumentation> X("ir-instrumentation", "LLVM IR Instrumentation Pass");
}
LLVM is configured and built fine with this pass but when I use opt, I get this error :
opt: /llvm/lib/IR/Type.cpp:281:
llvm::FunctionType::FunctionType(llvm::Type*, llvm::ArrayRefllvm::Type*, bool):
Assertion `isValidReturnType(Result) && "invalid return type for function"' failed.
I think the problem is something like mismatching between the function type that I have declared and the external function (like the context).
LLVM version: LLVM version 7.0.0svn
Until now I have not solved the problem.
Thanks
I could finally solve this problem and successfully instrument LLVM bitcode. After a lot of trouble with function getOrInsertFunction, I found out it is not really necessary to use this method in my case. I just simply changed my pass to this:
#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/IRBuilder.h"
#include <vector>
using namespace llvm;
namespace{
struct ir_instrumentation : public ModulePass{
static char ID;
Function *monitor;
ir_instrumentation() : ModulePass(ID) {}
virtual bool runOnModule(Module &M)
{
errs() << "====----- Entered Module " << M.getName() << ".\n";
int counter = 0;
for(Module::iterator F = M.begin(), E = M.end(); F!= E; ++F)
{
errs() << "Function name: " << F->getName() << ".\n";
if(F->getName() == "print"){
monitor = cast<Function>(F);
continue;
}
for(Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
{
for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI)
{
if(isa<BranchInst>(&(*BI)) )
{
errs() << "found a brach instruction!\n";
ArrayRef< Value* > arguments(ConstantInt::get(Type::getInt32Ty(M.getContext()), counter, true));
counter++;
Instruction *newInst = CallInst::Create(monitor, arguments, "");
BB->getInstList().insert(BI, newInst);
errs() << "Inserted the function!\n";
}
}
}
}
return true;
}
};
char ir_instrumentation::ID = 0;
static RegisterPass<ir_instrumentation> X("ir-instrumentation", "LLVM IR Instrumentation Pass");
}
As I know the name of the external function, I can simply find it through iterating over all functions of module and then use it in the desired way.
Obviously the problem was caused by calling module->getOrInsertFunction and the function type. My experience says that this method is more useful when you want to insert a new function and declare the prototype of your own function. Using it to get an existing function is challenging (e.g. setting the right prototype, ...)
Thanks

Writing c-style string to text file and returning information from text file

I'm trying to write a program that creates a structure for student info, has an array with 4 students info, writes the info to a text file, and returns the information back from the text file. I'm also supposed to do the same process with binary I/O, but that part works well so I took it out of the code. My issue is with the text file. I believe the issue is with the name part of the array. I also have the guideline to follow: "Do not use the string class in your struct definition. Instead, use the old c-style string (i.e. array of char)" I can't figure out how to get the program to step over the space between first/last names. This is the code I have written:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>
using namespace std;
/* structure */
struct studentInfo
{
char name[40];
int age;
float gpa;
char grade;
};
int main(int argc, const char * argv[])
{
const int SIZE = 4;
int i;
/* array */
studentInfo student[SIZE]{ {"Ann Annson\0", 10, 1.10, 'D'},
{"Bill Billson\0", 20, 2.20, 'C'},
{"Carl Carlson\0", 30, 3.30, 'B'},
{"Don Donson\0", 40, 4.00, 'A'} };
/* open & write to file in text mode i/o */
fstream fFile;
fFile.open("students.txt", ios::out);
for(i = 0; i < SIZE; i++)
{
fFile << student[i].name << endl;
fFile << student[i].age << endl;
fFile << student[i].gpa << endl;
fFile << student[i].grade << endl;
}
fFile.close();
/* open and read information from files to new arrays */
studentInfo studentsText[4];
fFile.open("students.txt", ios::in);
for(i = 0; i < SIZE; i++)
{
fFile >> studentsText[i].name;
fFile >> studentsText[i].age;
fFile >> studentsText[i].gpa;
fFile >> studentsText[i].grade;
}
fFile.close();
/* display the information from students.txt */
cout << "This is the data contained in students.txt: " << endl;
for (i = 0; i < SIZE; i++)
{
cout << studentsText[i].name << "\t" << studentsText[i].age;
cout << "\t" << studentsText[i].gpa << "\t" << studentsText[i].grade << endl;
}
return 0;
}
this is the output that I receive when I run the program:
screenshot
and this is the output I'm trying to get:
screenshot
I do know that it is an issue regarding the space, because if I run the program with the spaces between the names in the array removed it returns this output: screenshot
Forgive me if this is a poor question, I'm in my first semester of c++ and I hope that I worded this well for anyone that attempts to help. Thank you to everyone who looks at this and tries to help!
side note
this is the full code I have written
and this is the output I receive when running that code

Issue with making a loop

#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
string checkpass(string password1)
{
string rightpass = "aimen";
string errormsg2;
if (password1 == rightpass)
{
errormsg2 = "Right";
}
else{errormsg2 = "No";}
return errormsg2;
}
int main()
{
string password;
string errormsg;
cout << "Type the password";
loop:
getline (cin,password);
errormsg == checkpass(password);
if (errormsg=="Right")
{
cout << "Admitted" << endl;
}
else {
goto loop;
}
system("pause");
return 0;
}
Console doesn't print the word "Admitted". It launches, but after my putting in the console words, repeatedly occur nothing.
I request your aid. Thank you.
You are comparing with errormsg == checkpass(password); when you should assign with one = symbol.

how to access private array within member function in c++

Fruit.h
class Fruit
{
private:
std::int no[3];
public:
void initialize();
int print_type();
};
Fruit.cpp
#include "Fruit.h"
void Fruit::initialize() {
int no[] = {1, 2, 3};
}
int Fruit::print_type() {
return type[0];
}
Main.cpp
#include <iostream>
#include "Fruit.h"
using namespace std;
int main()
{
Fruit ff;
ff.initialize();
int output = ff.print_type();
cout << output;
system("pause");
return 0;
}
Assume the required directives are included inside all the files.
At this moment, I find a problem when getting back the ouput since it will not result in "0" but a garbage value. How can I fix it without using constructor?
Sincerely hope that someone would do me a favor.
This is the way that doesn't use constructors and destructors, I hope you find it useful.
#include <iostream>
class Fruit
{
private : int* no;
public : void initialize();
public : void clean();
public : int print_type();
};
void Fruit::initialize()
{
no = new int[ 3 ];
no[ 0 ] = 1;
no[ 1 ] = 2;
no[ 2 ] = 3;
}
int Fruit::print_type()
{
return no[ 0 ];
}
void Fruit::clean()
{
delete[] no;
}
int main()
{
Fruit f;
f.initialize();
int o = f.print_type();
std::cout << o;
f.clean();
return 0;
}
Please, read about constructor in C++. You don't know about the elementary things in OOP C++.
#include "Fruit.h"
void Fruit::initialize() {
int no[] = {1, 2, 3};
}
This is not correctly. You most write this.no or no.
int Fruit::print_type() {
return type[0];
}
What is variable type?

shared library how to link to a symbol?

I have:
car.cc
#include "car.h"
#include <iostream>
using namespace std;
extern "C" Car* create_object()
{
return new Car;
}
Car::Car() {
this->maxGear = 2;
this->currentGear = 1;
this->speed = 0;
}
void Car::shift(int gear) {
if (gear < 1 || gear > maxGear) {
return;
}
currentGear = gear;
}
void Car::brake() {
speed -= (5 * this->getCurrentGear());
std::cout<<"THE SPEED IS:" <<speed<<std::endl;
}
extern "C" void destroy_object( Car* object )
{
delete object;
}
car.h
#ifndef VEHICLES_CAR_H
#define VEHICLES_CAR_H
// A very simple car class
class Car {
public:
Car();
void shift(int gear);
void accelerate();
void brake();
private:
int maxGear;
int currentGear;
int speed;
};
#endif /* VEHICLES_CAR_H */
test.cc
#include "/home/car.h"
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
/* on Linux, use "./myclass.so" */
void* handle = dlopen("/usr/lib/libCarTest.so", RTLD_LAZY);
int (*result)(int);
if (!handle)
{
}
/*dlsym(handle,"accelerate");
cout<<"IN HERE: "<<endl;
dlsym(handle,"brake");
dlclose(handle);*/
Car* (*create)();
void (*destroy)(Car*);
dlerror();
create = (Car* (*)())dlsym(handle, "create_object");
destroy = (void (*)(Car*))dlsym(handle, "destroy_object");
Car* carr = (Car*)create();
carr->brake();
destroy( carr );
dlclose(handle);
/*
Car carr;
carr.brake();
* compilation g++ test.cpp -o tst /path/libcar.so
*/
return 0;
}
After creating libMyLib.so and install it in /usr/lib i've tried to compile test.cc using: g++ test.cc -o tst -ldl. WHY do i need to include -lMyLib? is there a way to compile the code without libMyLib.so? Secondly why dlsym(handle,"brake") is not working? If i change dlsym (Car* (*).... with dlsym(handle,"brake") i get nothing. why?
Appreciate
WHY do i need to include -lMyLib?
Because you need to link to the Car::brake method.
Secondly why dlsym(handle,"brake") is not working?
Because there is no brake symbol. The method Car::brake has a complicated mangled (implementation-defined) name. You can see this in the output of nm -D.
AFAIK, you can solve it by
making all the methods of Car virtual (they will be called through a pointer, so no linking will be needed)
doing it the old C way, ie. export a free function brake() that would call the Car::brake method from the .so
making all the public methods of Car inline and defining them in the header.
emulating the virtual table approach (as we do it in C)
Combining the last two approaches:
class Car {
public:
void brake() { brake_impl(this); }
private:
void (*brake_impl)(Car*);
void do_brake(); // this would be the actual implementation
Car() : brake_impl([] (Car* c){ c->do_brake(); }) { ... }
};
Of course you could split the implementation and the interface so it's not such a mess.

Resources