How to print value of a pointer

 pub fn push(&mut self)
    {
        if self.is_empty()
        {
            println!("The circular buffer is empty");
        } else
        {
            let _value = unsafe {
                let read_ptr = self.buffer.offset(self.tail);
                ptr::read(read_ptr)
                };
            println!("value is {}",_value);                    
            self.tail +=1; 
            self.realign_offsets(); 
            println!("self.tail value = {}",self.tail);
            
        }
    }

I am trying to print the _value but getting "T cannot be formatted with the default formatter".
How can I println! the _value?!

Note: Here's how to post code to this forum.


To answer your question, you need to use debug print:

println!("{:?}", _value);
2 Likes

I have implemented as you have shown and getting :

 use std::fmt::Debug;
  |     ^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error[E0277]: `T` doesn't implement `std::fmt::Debug`
  --> src/main.rs:67:29
   |
67 |             println!("{:?}",_value);
   |                             ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`

The code you posted doesn’t contain any definition of the type T, so it’s hard to figure out what’s going wrong. Can you show the rest of it?

1 Like

Abstract types like T are forbidden from supporting any operations that aren't explicitly enabled for them. You need to add where T: Debug to your generic code to limit it to only types that can be printed.

Unfortunately, this is going to be annoying for "printf debugging". If you just want to print raw pointer value, then printf!("{}", ptr as usize) might work.

For Debug types there's {:p} format pattern that prints their address.

3 Likes

{:p} works for all references and raw pointers.

5 Likes
// curcilar buffer implementation 
extern crate alloc;

use alloc::alloc::Layout; 
use std::{mem,ptr}; 
use std::fmt::Debug;

pub struct CircBuf<T> {
layout : Layout, 
max    : isize,
buffer : *mut T,  
head   : isize, 
tail   : isize, 
}

impl<T> CircBuf<T> {

pub fn new(n:usize) -> Self {
    assert_ne!(n,0);

    let align = mem::align_of::<T>();
    let element_size = mem::size_of::<T>();
    let layout = Layout::from_size_align(element_size*n,align)
        .expect("Memory layout problem.");
    let ptr = unsafe { alloc::alloc::alloc(layout) }  as *mut T; 

    CircBuf {
        layout,
        max : n  as isize, 
        buffer : ptr, 
        head: 0, 
        tail: 0, 
    }
}

pub fn put(&mut self, element:T) 
{
    //println!("{:p}",element);
    if self.is_full() 
    {
        println!("Sorry, The Buffer is full");
    } else 
    {
        unsafe {
            let write_ptr = self.buffer.offset(self.head % self.max);
            ptr::write(write_ptr, element); 
        }

        self.head +=1; 
        self.realign_offsets();
        println!("New self.head value= {} ",self.head);
      
    }
}

pub fn push(&mut self) 
{
    if self.is_empty() 
    {
        println!("The circular buffer is empty");            
    } else 
    {
        let _value = unsafe {
            let read_ptr = self.buffer.offset(self.tail);
            ptr::read(read_ptr)
            };
        //println!("{:?}",_value);
        self.tail +=1; 
        self.realign_offsets(); 
        println!("self.tail value = {}",self.tail);
        
    }
}

pub fn clear(&mut self) 
{
    self.tail = 0 ; 
    self.head = 0 ; 
}

pub fn ow(&mut self, element: T) {
    if self.is_full() { self.push();}

    self.put(element);
}

fn realign_offsets(&mut self) 
{
   // println!(" Welcome to realign ==> self.head={}, self.max={} self.tail={}",self.head,self.max,self.tail);

    if self.head >= self.max { self.head -= self.max;}
    if self.tail >= self.max { self.tail -= self.max;}
    
     //println!(" Final realign ==> self.head={}, self.max={} self.tail={}",self.head,self.max,self.tail);

}

fn is_full (&self) -> bool 
{
    self.head - self.tail == self.max 
}

fn is_empty(&self) ->bool 
{
    self.tail == self.head 
}
} 

impl<T> Drop for CircBuf <T> {
fn drop (&mut self) 
{
self.clear(); 
unsafe { alloc::alloc::dealloc(self.buffer as *mut u8, self.layout) };
}
}

fn main() {
assert!(true);
let mut cb = CircBuf::<char>::new(7);
cb.put('1'); 
cb.put('2');
cb.put('3');
cb.push();
cb.push();
cb.put('4');
cb.put('5');
cb.put('6');
cb.put('7');
cb.put('8');
cb.put('9');
cb.ow('A');
cb.ow('B');
cb.put('E');
cb.push();
cb.push();
cb.ow('C');
cb.ow('D');
cb.put('E');
println!("Hello, world!");
}

Line 67 is where I am trying to print...

It looks like the forum software is eating things in <angle brackets>, probably because it thinks they’re html tags. Can you edit your post to put the code in a code block? You just need to put three backticks around it, like this:

```
// circular buffer implementation
extern crate alloc;

use ...
```

Dear Sir,

I have changed the code as per your request.

Kind regards,

Thanks. The simple fix is to add a Debug requirement for T. This slightly limits what buffer items you can use, but not by much; all the primitive types implement it, as does most of the standard library:

impl<T:Debug> CircBuf<T> {
   /* your existing code */
}

I have changed the code but still getting errors :

error[E0277]: the trait bound `T: std::fmt::Pointer` is not satisfied
  --> src/main.rs:67:29
   |
67 |             println!("{:p}",_value );
   |                             ^^^^^^ the trait `std::fmt::Pointer` is not implemented for `T`
   |
   = note: required by `std::fmt::Pointer::fmt`
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
   |
16 | impl<T:Debug + std::fmt::Pointer> CircBuf<T> {
   |              ^^^^^^^^^^^^^^^^^^^

error[E0599]: no method named `clear` found for mutable reference `&mut CircBuf<T>` in the current scope
   --> src/main.rs:112:10
    |
112 |     self.clear(); 
    |          ^^^^^ method not found in `&mut CircBuf<T>`
    |
    = note: the method `clear` exists but the following trait bounds were not satisfied:
            `T: std::fmt::Debug`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `circ_buff`.

To learn more, run the command again with --verbose.

Does the same code compile on your PC?!

_value here is a T (char), so it doesn’t have any kind of pointer value — using {:p} here doesn’t make much sense, which is what the compiler is complaining about. What is the output that you’re expecting?

Sorry; I didn’t notice the Drop implementation. Copying the clear code there is the fastest way forward: what the previous change did is undefine all of those methods when T isn’t Debug. Since Drop doesn’t have that constraint, it can’t assume that clear is implemented.

I also just moticed that you’re mot calling any destructors, so you might want to limit T to Copy + Debug instead.

impl<T> Drop for CircBuf <T> {
    fn drop (&mut self) {
        self.tail = 0;
        self.head = 0;
        unsafe { alloc::alloc::dealloc(self.buffer as *mut u8, self.layout) };
    }
}

Without println! everything works fine, but I am trying to print out the value that I am dropping.

Your current code uses "{:p}" which takes a reference and prints the memory address of its internal pointer instead of the value it points to.

In your case, _value isn’ta reference; it’s just a plain number. For that, you want to use println!("{:?}”, _value).

error[E0277]: T doesn't implement std::fmt::Debug
--> src/main.rs:66:29
|
66 | println!("{:?}",_value);
| ^^^^^^ T cannot be formatted using {:?} because it doesn't implement std::fmt::Debug
|
= help: the trait std::fmt::Debug is not implemented for T
= note: required by std::fmt::Debug::fmt
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter T
|
15 | impl<T: std::fmt::Debug> CircBuf {
| ^^^^^^^^^^^^^^^^^

error: aborting due to previous error; 1 warning emitted

For more information about this error, try rustc --explain E0277.
error: could not compile circ_buff.

To learn more, run the command again with --verbose.

I have tried that one but getting this error.

Have you tried editing line 15 according to the compiler’s suggestion?

Thanks, it worked.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.