using global new and delete with dynamic lib - c++

I am trying to overload global new and delete. So I have created a separate lib to keep both however when I try to use them i am seeing that my mehotds do not get called. Someone could tell me why and how I could fix, please?
Here is my code:
file my_operator.cpp
#include <cstdlib>
#include <cstdio>
void* operator new(size_t size)
{
puts("constructing");
void* p = malloc(size);
return p;
}
void operator delete(void *p) throw()
{
puts("deleting");
free(p);
}
file myclass.h
class clase
{
private:
int x;
public:
clase(int i):x(i){}
inline int getX(){return x;}
};
main.cpp
#include "myclass.h"
int main()
{
int k = 5;
int ret = 0;
clase* c = new clase(k);
delete c;
return ret;
}
what I have tried so far:
running this:
g++ -c my_operator.cpp -o my_operator.o && g++ main.cpp my_operator.o -o main
then launching ./main --> it works, my operators get called
however
running this:
g++ -c my_operator.cpp -o my_operator.o
ld -o my_operator.so my_operator.o -shared to create the .lib file
and then
g++ main
and finally running ./a.out does not work properly, my operators do not get called
Any clue?
Thanks in advance!

Your commands don't link your main with my_operator.so. You need something like the following:
g++ -Wall -Wextra -c -fPIC -o my_operator.o my_operator.cpp
g++ -shared -o libmy_operator.so my_operator.o
g++ -Wall -Wextra -c -o main.o main.cpp
g++ -o main main.o -lmy_operator
./main

Your main.cpp does not know that you overloaded the operators.
Put your overload operators in the header file.
Usefull links on this matter:
http://en.cppreference.com/w/cpp/memory/new/operator_new
http://www.cprogramming.com/tutorial/operator_new.html

Related

Force alle functions in shared library to be defined

I want to write a shared library and I want to get a compiler/linker error if I forgot to implement some functions.
Consider the following case:
test.h
class Test {
public:
Test();
};
test.cpp
#include "test.h"
main.cpp
#include "test.h"
int main() {
new Test();
}
If I create a library with this command gcc -c -fpic test.cpp && g++ -shared -o libtest.so -Wl,--no-undefined -Wl,--no-allow-shlib-undefined test.o there is no error message, but the library is broken. Is there a way to force the creation of a not broken library?
Edit: adding additional flag, but doesn't change result
These codes have been modified:
test.h :
class Test {
public:
Test();
};
test.cpp :
#include "test.h"
Test::Test(){} // you must implement the constructor
You must have to implement the constructor, and if not, you get an error "undefined reference to `Test::Test()'".
main.cpp :
#include <iostream>
#include "test.h"
using namespace std;
int main(void)
{
Test* t = new Test(); // you must define a pointer
cout << "test* was created: " << t << endl;
delete t;
t = nullptr;
return 0;
}
Now all the code is OK. Then we create a shared-library with the following command:
g++ -shared -o test.so -fPIC test.cpp
Finally, we compile the main.cpp file at the same time as referring to the test.so shared-library and get the exe output, by the command below:
g++ -g main.cpp test.so -o test.exe

External String Call Causes Segfault in 32-bit, Works in 64-bit

I am writing a program that calls an external string array from within a compiled static library.
When I compile and run the program in 64-bit, it works without issue. However, when I try to call the external array when compiling code in* 32-bit*, it give a Segmentation Fault when running main.
Here is the code:
Header declaration "hoenyB_lib.h:
#ifndef HONEYB_LIB_H_
#define HONEYB_LIB_H_
#include <string>
extern std::string honeyB_libs[];
#endif
Extern definition HoneyB_lib.cpp:
#include <string>
std::string honeyB_libs[] = { "libHoneyB.so", "libHoneyB3.so", "libHoneyB2.so", "" };
Extern use HoneyB_fcn.cpp:
deque<string> get_array()
{
deque<string> dst;
int i =0;
for(;;)
{
if(honeyB_libs[i] == "")
break;
else
{
dst.push_front(honeyB_libs[i]);
i++;
}
}
return dst;
}
The Makefile to compile this is as follows:
all:
$(CC) -c -Wall -fPIC source.cpp
$(CC) -g -c -fPIC honeyB_fcn.cpp
ar rcs libHB.a honeyB_fcn.o
g++ -g -c -fPIC honeyB_lib.cpp
g++ --whole-archive -shared -o libHoneyB.so source.o honeyB_lib.o libHB.a
g++ -L. -o main main.cpp -lHoneyB
This works without issue when main() is called. However, when I compile as 32-bit with the following:
all32:
$(CC) -m32 -c -Wall -fPIC source.cpp
$(CC) -m32 -g -c -fPIC honeyB_fcn.cpp
ar rcs libHB.a honeyB_fcn.o
g++ -m32 -g -c -fPIC honeyB_lib.cpp
g++ --whole-archive -m32 -shared -o libHoneyB.so source.o honeyB_lib.o libHB.a
g++ -m32 -L. -o main main.cpp -lHoneyB
The code give a Segmentation Fault. If I remove the call in honeyB_fct.cpp to honeyB_libs[], the code compiles and executes.
Does anybody have any idea why this fails for 32-bit, but works for 64?
Thanks in advance.
Order of initialization between different translation units is undefined. You have no guarantee that global variables in HoneyB_lib.cpp will be initialized before they are used in HoneyB_fcn.cpp. The only reason it worked for the 64-bit version is because you got lucky.
There are a couple workarounds:
Define the array in honeyB_lib.h, wrapped in an anonymous namespace to get around the ODR. Each TU that includes your header will have its own copy of the array.
Again, define the array in the header, but put it inside of a function that returns the array. The compiler should optimize it out everywhere, but if not you can make the array static in the scope of the function and return by reference (i.e. make it a singleton).
As a side note, I'd recommend a std::array instead of a raw array; this will let you do honeyB_libs.size() (or even for (auto&& lib : honeyB_libs) {...}) instead of relying on the "" sentinel value, which would clean up your get_array function a bit.
Thank you for the help. It appears that the problem had to do with the bit count of strings in 32-bit vs 64-bit. Changing honeyB_libs[] from a string array to a const char* array solved the issue.
honeyB_lib.h
extern const char* honeyB_libs[];
honeyB_lib.cpp
const char* honeyB_libs[] = { "libHoneyB.so", "libHoneyB3.so", "libHoneyB2.so", "" }
function.cpp
deque<string> get_array()
{
deque<string> dst;
string temp;
int i =0;
for(;;)
{
if(strlen(honeyB_libs[i]) == 0)
break;
else
{
temp = honeyB_libs[i];
dst.push_front(temp);
i++;
}
}
return dst;
}
Doing this allows my program to compile and run as 64-bit and 32-bit

C++ shared library undefined reference

i'm having something like these files:
libfoo.h
class foo
{
public:
foo() = default;
virtual ~foo();
};
libfoo.cpp
#include "libfoo.h"
foo::~foo() { /* code here */ }
test.cpp
#include <libfoo.h>
int main()
{
foo f;
}
i compile libfoo.h and libfoo.cpp into a shared library and all that is fine.
but when i then try to use the library in test.cpp i get undefined reference to the destructor ~foo().
this error however does not occur if i define the destructor directly in libfoo.h. i have this problem with all functions defined outside the class in my library so im guessing it has something to do with the compilation process (it compiles fine however)
i compile the library like this:
g++ -std=c++0x -Wall -Werror -fPIC -c -o libfoo.o libfoo.cpp
g++ -shared libfoo.o -o libfoo.so
any ideas as to what i might be doing wrong?
(all the functions that i declare inclass, like template functions works fine and causes no undefined reference)
I tried to reproduce the error, but I failed.
I created the files (with slight modifications):
// libfoo.h
struct foo { virtual ~foo(); };
// libfoo.cpp
#include "libfoo.h"
foo::~foo() {}
// test.cpp
#include "libfoo.h"
int main() { foo f; }
Built like this:
$ g++ -std=c++0x -Wall -Werror -fPIC -c -o libfoo.o libfoo.cpp
$ g++ -shared libfoo.o -o libfoo.so
$ g++ test.cpp -L. -lfoo
And ran like this:
$ env LD_LIBRARY_PATH=. ./a.out
I got no errors. Are you sure there is a problem with your code?

resolved: c++ : put normal method definition into source file while the templates method in header file

Since the definition of template must be put in header file, so I don't like it if the template class is big. so I want to make a normal class with some templated methods. Putting the defintion of templated method into header file, for others, put them into c++ source files. So here is what I am thinking.
// lambda.h
#include <iostream>
class X {
public:
std::function<bool(int)> filter;
template <class F>
void setFilter(F fn) {
filter = fn;
}
void big_function(int x);
};
// cat lambda.cpp
#include <iostream>
#include "lambda.h"
void X::big_function(int x) {
if (filter(x)) std::cout << x << std::endl;
}
// main2.cpp
#include <stdlib.h>
#include "lambda.h"
class Filter {
public:
bool operator()(int x) { return true; }
};
int main() {
X x;
x.setFilter(Filter());
x.big_function(3);
return 0;
}
// cat 2.sh
g++ -c lambda.cpp -ggdb
g++ -c main2.cpp -ggdb -std=c++11
g++ -o main2 main2.o lambda.o -ggdb
this program can compile, but got segment fault during executing (x.big_function(3));
#update
Q1: is my thinking is reasonable? is there any obvious error in my code?
Answer: Yes, it is reasonable, and no obvious error. Thanks to the first 4 comments, I did more test and works.
Q2: actually if I compile with -std=c++11, I will got segment fault. but no segment fault if I don't use std=c++11. ( I tried c++11 yesterday because I used lambda expression rather than function object for "Filter" at beginning). And it my real case, I can't discard c++11 features.
Answer: shame about my fault. fixed the issue by adding -std=c++11 for every compile unit.
zhifan$ sh -x 2.sh
+ g++ -c lambda.cpp -ggdb
+ g++ -c main2.cpp -ggdb
+ g++ -o main2 main2.o lambda.o -ggdb
zhifan$ ./main2
3
zhifan$ vim 2.sh
hifan$ sh -x 2.sh
+ g++ -c lambda.cpp -ggdb **-std=c++11**
+ g++ -c main2.cpp -ggdb -std=c++11
+ g++ -o main2 main2.o lambda.o -ggdb
zhifan$ ./main2
Segmentation fault: 11
zhifan$ g++ -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix

Compilation issue in calling function of .o file in .cpp

I have a temp1.c file having a function
int add(int a, int b){ return (a+b); }
and temp1.h file
int add(int,int)
I have created .o file from it by compiling
g++ -o temp1.o -c temp1.cpp
Now I have to use add function in temp2.cpp placed in a different directory. I have done
#include "temp1.h"
int main(){
int x = add(5,2);
}
I have to compile temp2.cpp with temp1.o so that I can create a temp2.exe which can call function add. How to compile it?
g++ temp2.cpp temp1.o -o temp2.exe
Like this:
temp2: temp1.o temp2.o
g++ temp1.o temp2.o -o temp
temp1.o: temp1.cpp
g++ -c temp1.cpp -o temp1.o
temp2.o: temp2.cpp
g++ -c your/path/to/temp2.cpp -o temp2.o