Declare const pointer to int? - pointers

In C++ we have the following:
int* p1; // pointer to int
const int* p2; // pointer to constant int
int* const p3; // constant pointer to int
const int* const p4; // constant pointer to constant int
and in D:
int* p1; // pointer to int
const(int)* p2; // pointer to constant int
?? ?? ?? // constant pointer to int
const(int*) p4; // constant pointer to constant int
what's the syntax for constant pointer to int?

D does not have head const.

I think you can simulate it:
struct Ptr(T)
{
T* _val;
this(T* nval) const
{
_val = nval;
}
#property T* opCall() const
{
return cast(T*)_val;
}
alias opCall this;
}
void main()
{
int x = 1;
int y = 2;
const Ptr!int ptrInt = &x;
assert(*ptrInt == 1);
*ptrInt = y; // ok
assert(*ptrInt == 2);
assert(x == 2);
ptrInt = &y; // won't compile, good.
}

Related

Casting a const void* pointer parameter into a const char* pointer, in memchr function

I have to reproduce the functioning of the memchr function, which returns the pointer of the first int c occurence.
Of course, size_t n argument has been measured by func strlen before being sent to ft_memchr func parameter.
But I keep on getting this compiling error (compiled with a main.c) "
ft_memchr.c:10:21: error: operand of type 'const void' where arithmetic or pointer type is required
if ((const char *)s[i] == (const char)c)
"
I'm clearly missing something... It seems I can't cast the const void* parameter into a const char* or even a char*, why is that ?
Thank you.
#include <string.h>
void *ft_memchr(const void *s, int c, size_t n)
{
size_t i;
i = 0;
while (i < n)
{
if ((const char *)s[i] == (const char)c)
return ((char *)s + i);
}
return (NULL);
}

memory calculation is going negative while using malloc_hook

I want to track memory usage through the the program execution. I have used malloc_hook to capture all the memory related calls. below is the program
long int memory_bytes_hook = 0;
long int peak_memory_hook = 0;
std::mutex memory_mutex_hook;
static void my_init_hook (void);
static void *my_malloc_hook (size_t, const void *);
static void my_free_hook (void*, const void *);
static void* my_realloc_hook (void *ptr, size_t size, const void *caller);
static void *(*old_malloc_hook)(size_t, const void *);
static void (*old_free_hook)(void*, const void *);
static void *(*old_realloc_hook)(void *ptr, size_t size, const void *caller);
static void
my_init_hook (void)
{
__malloc_hook = my_malloc_hook;
__free_hook = my_free_hook;
__realloc_hook = my_realloc_hook ;
}
static void *
my_malloc_hook (size_t size, const void *caller)
{
const std::lock_guard<std::mutex> lock(memory_mutex_hook);
void *result;
__malloc_hook = nullptr;
__free_hook = nullptr ;
__realloc_hook = nullptr ;
result = malloc (size);
memory_bytes_hook += malloc_usable_size(result);
if(peak_memory_hook < memory_bytes_hook )
peak_memory_hook = memory_bytes_hook ;
my_init_hook();
return result;
}
static void* my_realloc_hook (void *ptr, size_t size, const void *caller)
{
const std::lock_guard<std::mutex> lock(memory_mutex_hook);
__malloc_hook = nullptr;
__free_hook = nullptr;//old_free_hook ;
__realloc_hook = nullptr;//old_realloc_hook ;
long int oldSize = malloc_usable_size(ptr);
void *result = realloc(ptr, size);
long int updated_size = malloc_usable_size(result);
memory_bytes_hook += (updated_size - oldSize);
if(peak_memory_hook < memory_bytes_hook )
peak_memory_hook = memory_bytes_hook ;
my_init_hook();
return result;
}
static void
my_free_hook (void *ptr, const void *caller)
{
const std::lock_guard<std::mutex> lock(memory_mutex_hook);
__malloc_hook = nullptr;// old_malloc_hook;
__free_hook = nullptr;// old_free_hook ;
__realloc_hook = nullptr;//old_realloc_hook ;
/* Call recursively */
long int oldSize = malloc_usable_size(ptr);
free (ptr);
memory_bytes_hook -= oldSize;
if(peak_memory_hook < memory_bytes_hook )
peak_memory_hook = memory_bytes_hook ;
my_init_hook();
}
int main(int argc, char** argv)
{
my_init_hook();
... calling other libraries and do lot of operation for couple of hours...
std::cout <<"At last: peak_memory hook: "<< peak_memory_hook << "\t" << " Bytes
allocated: " << memory_bytes_hook << "\n";
return 0;
}
At the end of program execution I am getting negative value of memory_bytes_hook . I did put some logs at intermediate intervals. It was observed that memory_bytes_hook value started reducing after some time and eventually went to negative. That's why It is not because of overflow. I was wondering , What could be other reason of it going negative value. I was hoping, malloc hook would catch all the memory related calls.

Looking for Segmentation Fault in C script

Hi trying to learn C specifically how to use pointers.
I wrote this script to practice ideas I've learned, but it crashes with segmentation fault error.
Bit of research search suggests that I am trying to access something that I should not be accessing I think that is an uninitialized pointer but I can't find it.
#include <stdio.h>
struct IntItem {
struct IntItem* next;
int value;
};
struct IntList {
struct IntItem* head;
struct IntItem* tail;
};
void append_list(struct IntList* ls, int item){
struct IntItem* last = ls->tail;
struct IntItem addition = {NULL,item};
last->next = &addition;
ls->tail = &addition;
if (!ls->head) {
ls->head = &addition;
}
}
int sum(int x, int y){
return x + y;
}
int max(int x, int y){
return x*(x>y) + y*(y>x);
}
int reduce(struct IntList xs, int (*opy)(int, int)){
struct IntItem current = *xs.head;
int running = 0;
while (current.next) {
running = opy(running,current.value);
current = *current.next;
}
return running;
}
int main(void) {
struct IntList ls = {NULL, NULL};
printf("Start Script\n");
append_list(&ls, 1);
append_list(&ls, 2);
append_list(&ls, 3);
printf("List Complete\n");
printf("Sum: %i",reduce(ls,sum));
printf("Max: %i",reduce(ls,max));
return 0;
}
Hints:
When you call append_list(&ls, 1), then inside append_list, what is the value of last?
What does last->next = &addition do?
And for your next bug:
What happens to addition after append_list returns? What does that mean for pointers to it?

Constant container (map) - eliminate heap allocation

If I create a static const std::map, it will allocate memory on heap. Following code throws bad_alloc:
#include <iostream>
#include <map>
class A {
public:
static const std::map<int, int> a;
};
const std::map<int, int> A::a = { { 1, 3} , { 2, 5} };
void* operator new ( std::size_t count )
{
throw std::bad_alloc();
}
int
main (void)
{
for(auto &ai: A::a) {
std::cout << ai.first << " " << ai.second << "\n";
}
return 0;
}
Is it possible to create this constant map somehow without having memory allocation?
As Igor Tandetnik suggested, a custom allocator would do the trick. The following is a quick'n'dirty example of a simple linear allocator, which returns memory slots from a static buffer:
#include <iostream>
#include <map>
#include <cassert>
template <typename T>
class LinearAllocator {
static constexpr size_t _maxAlloc = 1<<20;
using Buffer = std::array<T, _maxAlloc>;
using FreeList = std::array<bool, _maxAlloc>;
static Buffer _buffer;
static FreeList _allocated;
public:
typedef T* pointer;
typedef T value_type;
template<typename U>
struct rebind { typedef LinearAllocator<U> other; };
pointer allocate(size_t /*n*/, const void *hint=0) {
for(size_t i = 0; i < _maxAlloc; ++i) {
if(!_allocated[i]) {
_allocated[i] = true;
return &_buffer[i];
}
}
throw std::bad_alloc();
}
void deallocate(pointer p, size_t /*n*/) {
assert(p >= &_buffer[0] && p < &_buffer[_maxAlloc]);
_allocated[p-&_buffer[0]] = false;
}
LinearAllocator() throw() { }
LinearAllocator(const LinearAllocator &a) throw() { }
template <class U>
LinearAllocator(const LinearAllocator<U> &a) throw() { }
~LinearAllocator() throw() { }
};
template <typename T>
typename LinearAllocator<T>::Buffer LinearAllocator<T>::_buffer;
template <typename T>
typename LinearAllocator<T>::FreeList LinearAllocator<T>::_allocated;
using MyMap = std::map<int, int, std::less<int>,
LinearAllocator<std::pair<int,int> > >;
// make sure we notice if new gets called
void* operator new(size_t size) {
std::cout << "new called" << std::endl;
}
int main() {
MyMap m;
m[0] = 1; m[1] = 3; m[2] = 8;
for(auto & p : m)
std::cout << p.first << ": " << p.second << std::endl;
return 0;
}
Output:
0: 1
1: 3
2: 8
Note that this allocator will only handle requests for single slots at a time. I'm sure you will figure out how to extend it according to your requirements.

How is unsigned int *ptr treated as prt[i]?

int *c;
int d,noofentries;
struct A
{
unsigned int *ptr;
int entry;
}a;
a->ptr=memalloc(34,unsigned int);
a->ptr = (unsigned int*) entry
nofoentries = 8 ;
d =56749;
for(i=0;i<noofentries;i++)
{
c[i] = d; // how is a pointer treated as array ?
}
for(i=0;i<34;i++)
{
a->ptr[i] = c[i]; //segmentation fault occurs
}
I require the assignment of the values populated in c[i] to be assigned to a->ptr[i]. So that when a->ptr[i] deleted then c[i] is also freed.
Kindly help!!
generally you would not want your pointer to be treated as an array, rather you would have an array and use its name as pointer to refer to any particular member of the array
for e.g
int arr[5];
//the array name 'arr' points to the zeroth element
so now you can use *(arr+ indexNo) = value or arr[indexNo] = value, to assign a value to a particular element
you would want to use your pointer as an array, when you have assigned an array to it.
for e.g
int arr[5];
int *ptr;
if you do
ptr = arr;
you can access ptr as you would have accessed arr
as
ptr[index]= value;
a pointer to a type is just the same than an array of the type
*( c + x ) = a
<=>
c[x] = a;
c + x find the right pointer position since it adds x * sizeof(type) to c pointer.
your code compiling under gcc :
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
struct A { unsigned int *ptr; int entry; };
int main(int argc, char ** argv)
{
unsigned int * c;
unsigned int d;
int noofentries, i;
struct A a;
noofentries=34;
c=malloc(noofentries * sizeof(unsigned int));
d =56749;
for(i=0;i<noofentries;i++) { c[i] = d; }
// no need to copy full array c, since ptr is a pointer over it...
a.ptr = c;
// warning if above line is not done then allocation of ptr is required:
// a.ptr = malloc(noofentries * sizeof(unsigned int));
// and content copy
// for(i=0;i<noofentries;i++) { a.ptr[i] = c[i]; }
for(i=0;i<noofentries;i++) {
assert( a.ptr[i] == *(c + i) );
printf("a.ptr[%u]=%u\n",i,*(a.ptr + i));
}
free(c);
}

Resources