address allocation in linux : possible over lap? - linux

I am trying to check if my program is assigning memory correctly -
so i have series of pointers of different types,
pData1 = 0x844c458 ( result of malloc(5 * size of (double*))
pData2 = 0x844c470 (result of malloc (10 size of (double));
pData3 = 0x844c3a0(result of malloc(44 * size 0f (double*));
pData4 = 0x844c358
So i think double = 8 bytes , 5 *8 = 40 bytes, which means first two addresses will overlap and similarly last two ?
I am getting invalid free, so i am investigating a memory corruption in my code so trying to find where this might be happening.
-----Edit ------- Adding code details
THis is the struct -
struct _ELEMENT
{
short s;
char arr[20];
int size;
void *ptr1;
void *ptr2;
}ELEMENT;
There are two classes Parent and Derived ( child of Parent)
Class Parent
{
protected:
int size;
ELEMENT *ele1;
ELEMENT *ele2;
public:
void func();
...
}
Class Child::public Parent
{
int a,b,c;
}
Parent::Parent()
{
ele1 = NULL;
ele2= NULL;
}
Parent::~Parent()
{
for (int i =0; i< size; i++)
{
free(ele1[i].p1);
free(ele2[i].p1);
}
free(ele1);
free(ele2);
}
Child::Child()
{
a=0;...
}
Child::~Child()
{
for (int i =0; i< size; i++)
{
free(ele1[i].p1);
free(ele2[i].p1);
}
free(ele1);
free(ele2);
}
Parent::func ()
{
ele1 = (ELEMENT*)malloc (n * sizeof(ELEMENT));
ele2 = (ELEMENT*)malloc (n* sizeof(ELEMENT));
for (int i =0; i <somenumber; i++)
{
...some processing...
ele1[i].size = n;
ele2[i].size = x;
ele1[i].p1 = malloc (ele1[i].size);
ele2[i].p1 = malloc(ele2[i].size);
}
}
main ()
{
Parent *p;
CHild *c;
p = new Parent();
c= new Child();
p->func();
c->func();
delete(p);
delete(c);
}
The _glibc:invalid free comes at first free of parent destructor. This code was working fine in SOlaris for years but porting it in linux is giving this issue...
Thanks!

The answer to your question is that your program is allocating memory correctly, the first problem you had/have is that you don't know the size of your data types and so your computations are incorrect.
If you would post your code and the actual errors that you are getting, it's possible that we can figure this out. As it is, the deep problem of invalid free cannot be answered.
To whom it may concern, is this an answer or a comment?

sizeof(double) is 8 bytes and sizeof(double*) is 4 (on your 32 bit system).
Memory obtained by malloc will not overlap unless freed in the meantime.
Use a memory debugger such as valgrind

It looks that way... how did you end up with these pointers? In principle it's OK to have different pointers pointing to the same space - you just shouldn't be "freeing" except from a pointer that was assigned with malloc (or calloc). The glibc actually keeps some data "just below the pointer" that tells it how big the block is etc, so it can free "cleanly". If you change the value of the pointer, you can't "free part of a block" since the information about how big the block is isn't available (only if the pointer is unchanged). Could that be the source of your problem?

Related

Finding addresses of called functions C

I want to find addresses of functions on stack without using builtin macros or some library functions.(I know that all functions are called with call rel32) So what I want to do is: get address of local variable, iterate through stack looking for 0xe8 byte (opcode of call) and if I find it function's address should be 5 bytes further. This is what I have know:
extern void *__libc_stack_end;
void stack_show() {
int x;
for (uint8_t* i = &x; i < __libc_stack_end; i++) {
if(i == 0xe8) {
int64_t *a = i + 5;
printf("%p\n", a);
}
}
}
But it doesn't work. I'm not sure if types of my variables are OK.I'm using Linux and x86 architecture.
Any help appreciated.
Thanks.

Danger of using std::sort with vector of shared_ptr in multi-threaded world

This is simplified version(C++11) of issue I am facing when I upgraded an app to multithreaded world. Essentially I have vector of shared_ptr and I am doing std::sort on it. When multiple threads try to sort it, I can understand, its dangerous as while sorting, first time, iterators may have to move around. But, here, I already have a sorted vector . Now calling, std::sort on it shouldn't impose any trouble(that's what I thought as nothing needs to move) but it's crashing, randomly.( now why I call std::sort on a sorted container, actually, in original code, data is unsorted, but that doesn't matter for end result it seems). Here is sample code
#include <iostream>
#include <thread>
#include <vector>
#include <boost/shared_ptr.hpp>
const int MAX = 4;
#define LOOP_COUNT 200
struct Container {
int priority;
Container(int priority_)
: priority( priority_)
{}
};
struct StrategySorter {
int operator()( const boost::shared_ptr<Container>& v1_,
const boost::shared_ptr<Container>& v2_ )
{
return v1_->priority > v2_->priority;
}
};
std::vector<boost::shared_ptr<Container>> _creators;
void func() {
for(int i=0; i < LOOP_COUNT; ++i) {
std::sort( _creators.begin(), _creators.end(), StrategySorter() );
}
}
int main()
{
int priority[] = {100, 245, 312, 423, 597, 656, 732 };
size_t size = sizeof(priority)/sizeof(int);
for(int i=0; i < size; ++i)
{
_creators.push_back(boost::shared_ptr<Container>(new Container(priority[i])));
}
std::thread t[MAX];
for(int i=0;i < MAX; i++)
{
t[i] = std::thread(func);
}
for(int i=0;i < MAX; i++)
{
t[i].join();
}
}
Error :
../boost_1_56_0/include/boost/smart_ptr/shared_ptr.hpp:648: typename boost::detail::sp_member_access::type boost::shared_ptr::operator->() const [with T = Container; typename boost::detail::sp_member_access::type = Container*]: Assertion `px != 0' failed.
Having raw pointers doesn't crash it, so it's specific to shared_ptr.
Protecting std::sort with mutex is preventing crash.
I am not able to understand why this scenario should result into inconsistent behavior.
When more than one thread accesses the same data without synchronisation and at least one of them is doing a modifying operation, it is a race condition and as such, Undefined Behaviour. Anything can happen.
std::sort requires mutable iterators to operate, so it is by definition a modifying operation, therefore applying it concurrently to overlapping ranges withough synchronisation is a race condition (and thus UB).
There is no guarantee that a sort that ends up not moving elements will not write.
It could want to move pivots around, sort some stuff backwards in an intermediate stage, or even call swap(a,a) without a self-check optimization (as the check might be more expensive than the swap).
In any case, an operation that if it doesn't do nothing is UB is a horrible operation to invoke.
Here is a sort guaranteed to do nothing if nothing is to be done:
template<class C, class Cmp>
void my_sort( C& c, Cmp cmp ) {
using std::begin; using std::end;
if (std::is_sorted( begin(c), end(c), cmp ))
return;
std::sort( begin(c), end(c), cmp );
}
but I wouldn't use it.

Do I need a mutex on a vector of pointers?

Here is a simplified version of my situation:
void AppendToVector(std::vector<int>* my_vector) {
for (int i = 0; i < 100; i++) {
my_vector->push_back(i);
}
}
void CreateVectors(const int num_threads) {
std::vector<std::vector<int>* > my_vector_of_pointers(10);
ThreadPool pool(num_threads);
for (for int i = 0; i < 10; i++) {
my_vector_of_pointers[i] = new std::vector<int>();
pool.AddTask(AppendToVector,
&my_vector_of_pointers[i]);
}
}
My question is whether I need to put a mutex lock in AppendToVector when running this with multiple threads? My intuition tells me I do not have to because there is no possibility of two threads accessing the same data, but I am not fully confident.
Every thread is appending different std::vector (inside AppendToVector function) so there is no need for locking in your case. In case you change your code in the way more than one thread access same vector then you will need lock. Don't be confused because std::vectors you are passing to AppendToVector are them-selfs elements of main std::list, it matters only that here threads are manipulating with completely different (not shared) memory

VS2012 Static Analysis: this pointer as an output pointer?

In this code snippet, the Init() function acts as a on-demand initializer that fills in all member variables of the structure. This is done to avoid calling default constructors all members of a large array on the stack:
struct Foo {
int m_Member;
void Init(int i);
};
void Foo::Init(int i) {
m_Member = i;
// Many other members initialized here.
}
void SomeFunction(int n) {
Foo buffer[64];
assert(n <= 64);
// Explicitly initialize what is needed.
for (int i = 0; i < n; ++i) {
buffer[i].Init(i * 3);
}
// Use buffer[0] - buffer[n-1] somehow.
}
This triggers a static analysis error in VS2012 with /analyze:
warning C6001: Using uninitialized memory 'buffer'.: Lines: 17, 19, 20
I'm looking for a way to annotate Foo::Init() so that this warning doesn't occur. There are plenty of other ways to make the warning go away, including:
Adding an empty constructor
Moving Init() to the constructor and calling placement new in the loop
But I'd like to avoid changing the structure of the code.
I've tried the following annotation without success:
void _At_(this, _Out_) Init();
This syntax is accepted, but only changes the warning to be:
warning C6001: Using uninitialized memory 'buffer'.: Lines: 18, 20, 21
warning C6001: Using uninitialized memory 'buffer[BYTE:0]'.: Lines: 18, 20, 21
Does anyone know how I can declare the intent of this Init() function to the static analysis engine?
Your question is somewhat elusive. You have shown SomeFunction taking int, but want annotation for method Init or constructor.
The warning shown is absolutely correct, assert won't hide the warning. You need to put if to check if n is greateer than 64 and reset n (or do something else, but not to loop when n>=64).
For annotation you need to use __in_bcount or similar alternative. An example:
bool SetBuffer(__in_bcount(8) const char* sBuffer);
Whichs says sBuffer is of 8 bytes (not elements).
You can read this this article for more information.
Too ugly to add an extra helper?
struct Foo {
int m_Member;
void Init(int i);
};
void Foo::Init(int i) {
m_Member = i;
// Many other members initialized here.
}
void Initialize(__in_bcount(sizeof(Foo) * n) Foo* buffer, int n) {
// Explicitly initialize what is needed.
for (int i = 0; i < n; ++i) {
buffer[i].Init(i * 3);
}
}
void SomeFunction(int n) {
Foo buffer[64];
assert(n <= 64);
Initialize(buffer, n);
// Use buffer[0] - buffer[n-1] somehow.
}
I found a work around by implementing a function to index the array. I flagged the return value as invalid so that this new function only escapes the uninitialized value check in the specific case where the return value is only used to initialize. I've only tested this in VS2017.
#define _Ret_invalid_ _SAL2_Source_(_Ret_invalid_, (), _Ret1_impl_(__notvalid_impl))
template <typename T>
_Ret_invalid_ T& UninitialzedIndex(T* pt, int index)
{
return pt[index];
}
Then, where the value is indexed, I call UninitialzedIndex instead of operator[]
void SomeFunction(int n) {
Foo buffer[64];
if (n <= 64)
return;
// Explicitly initialize what is needed.
for (int i = 0; i < n; ++i) {
UninitialzedIndex(buffer, i).Init(i * 3);
}
// Use buffer[0] - buffer[n-1] somehow.
}
Just add a default constructor (that calls Init()). What is wrong with that?
[Edit] The root problem is not how to lie to the static analyzer or your compiler. It is how to enforce that you don't leave foo in an uninitialized state. There is nothing wrong with adding a default constructor. I'd say the desire to NOT do it imposes risk.
Perhaps some client will use that poorly constructed foo class (Long after you wrote it and long after you are gone) and perhaps they will forget to call .Init() ?? What then? They will be left with data that is uninitialized.
If you are looking to enforce that rule, no amount of static analysis will help you there.
Take care of the foundation before you put on the roof.

Invalid read and write of size in valgrind

I have invalid read of size in the following functions using valgrind. I'm not exactly sure why but if any of you can help me that would be greatly appreciated! From what I can tell it runs okay but there are still some errors that I'm not catching that may even deal with memory allocation and deallocation. Please help!
//alternate constructor that allows for setting of the inital value of the string
MyString::MyString(const char *message)
{
int counter(0);
while(message[counter] != '\0')
{
counter++;
}
Size = counter;
**String = new char [Size];**
for(int i=0; i < Size; i++)
String[i] = message[i];
}
istream& operator>>(istream& input, MyString& rhs)
{
char* t;
int size(256);
t = new char[size];
input.getline(t,size);
**rhs = MyString(t);**
delete [] t;
return input;
}
/*Assignment operator (=) which will copy the source string into the destination string. Note that size of the destination needs to be adjusted to be the same as the source.
*/
MyString& MyString::operator=(const MyString& rhs)
{
if(this != &rhs)
{
delete [] String;
**String = new char[rhs.Size+1];**
Size = rhs.Size;
for(int i = 0; i < Size; i++)
{
** String[i] = rhs.String[i];**
}
}
return *this;
}
Any suggestions?? (All of the problem lines have **)
One thing I see is that your copy constructor doesn't allocate space for \0 and doesn't copy it. Neither does the assignment operator.. Or, if you don't store terminating zero, then why are you looking for it?
and the two implementations differ, why the inconsistency (Size vs counter)?
"From what I can tell it runs okay" - it's called undefined behaviour, or in this case: luck - or, if you like me, and like to catch bugs: a misfortune.

Resources