0

I'm modifying some code I found to be inside a C++ object. Message is a c++ class.

The original line of code looks like this:

unsigned char fifoQueue[256 * sizeof(Message)] = {0};

Since I'm putting it into an object, I'm doing this:

///in header
unsigned char fifoQueue;

///in object initializer
fifoQueue = new unsigned char[256 * sizeof(Message)];

Somehow I don't think that is correct. What's the correct implementation to get the same result? I'm just a bit cloudy about how this works - In the given example fifoQueue is a pointer to a memory location, correct? Should my object have the fifoQueue instance variable as a pointer to a "Message" array, instead?

Thanks!

/////// Okay, I'm adding some information here that is relevant to the way this is being used. Sorry for not including this before.

There is a method that accesses this value as a pointer and increments it based on a read/write location. So I need the new initializer such that this method works correctly.

Message* Fifo::getMessageToWrite(){

    Message* base = (Message*)fifoQueue;
    return new(base + (fifoWritePtr & 255)) Message();

}
olynoise
  • 2,016
  • 2
  • 19
  • 32
  • Check [C/C++ initialization of a normal array with one default value](http://stackoverflow.com/q/1065774/1168156). – LihO Jan 31 '12 at 20:35
  • 1
    This looks like an XY problem, so there's probably a much better solution, but for now try `std::vector fifoQueue` and initialize it with `fifoQueue(256 * sizeof(int))`. – Kerrek SB Jan 31 '12 at 20:35
  • Why don't you like the original? – Christian Ammer Jan 31 '12 at 20:36
  • I made an edit --- int has been replaced by Message, since really its an array of objects.... – olynoise Jan 31 '12 at 20:39
  • Christian- I'd like it to be an instance variable. So I believe I need to declare the instance variable in the header and then initialize it in the initializer. I don't think I can do that directly in the header, can i? – olynoise Jan 31 '12 at 20:42
  • In my understanding yes, if you know the array size, you can declare it on the stack. You can declare the array like `Message fifoQueue[256]` and if you need a pointer to a specific element `return &fifoQueue[x]` – Christian Ammer Jan 31 '12 at 20:56

3 Answers3

1

From the looks of it, you want to pass objects of type Message through a queue. For this, the proper C++ mechanism is to use std::queue<Message>: it will grow to an appropriate size when pushing new messages into the queue. Unlike the std::vector<T> proposed in other answers, this actually uses a std::deque<Message> under the hood (you can use a std::deque<Message> directly but if you want a queue just use a queue).

The advantage of using a std::queue<Message> is that the object inside this queue stays put while they keep being shuffled around in a std::vector<Message>: while std::vector<T> only supports efficient (i.e. O(1)) addition/removal at the back as is e.g. used for a stack (LIFO), std::deque<T> supports efficient addition/removal at both ends as is needed for a queue (FIFO). I think the complexity of adding/removing to a std::deque<T> is only amortized constant but this is still better than linear complexity you'd get with a std::vector<T> when using it as a FIFO.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
0

The second version declares an unsigned char and tries to assign a unsigned char* to it. This is not going to work and even so it is not clear to me why you would allocate enough space for 256 intS and assign them to a unsigned char* unless you are doing something very low level. A std::vector is probably the better choice anyway.

pmr
  • 58,701
  • 10
  • 113
  • 156
  • Sorry, I've made an edit here to reflect the problem better. Instead of Int, the fifoQueue is for storing an object called Message. – olynoise Jan 31 '12 at 20:37
  • @olynoise And you are sure that the code accessing `fifoQueue` deals with alignment, padding and endianess? Otherwise I don't see why you are using a pointer to `unsigned char`? – pmr Jan 31 '12 at 20:42
  • @olynoise You maybe should not refactor this without knowing what you are doing. It looks dangerous. – pmr Jan 31 '12 at 20:46
  • @olynoise By reading and writing code (that is not over your head) and with a good book. – pmr Jan 31 '12 at 21:10
0

Piece of cake: std::vector is more preferable way instead of manual dynamic memory allocation (plain-old pointers).

#include <vector>
...
std::vector<char> fifoQueue(256);