简体   繁体   English

在函数中返回无符号字符数组,但不返回指针

[英]Returning unsigned char array in a function but not the pointer

I am implementing a simple class in C++ which have only one attribute that has to be unsigned char array and two methods, one get and one set. 我正在C ++中实现一个简单的类,该类仅具有一个必须为unsigned char array属性和两个方法,一个为get和一组。 I am struggling to define this unsigned char array. 我正在努力定义此无符号字符数组。 I defined the attributed as a pointer, but the get method cannot return a pointer because this is an undefined behavior. 我将属性定义为指针,但是get方法无法返回指针,因为这是未定义的行为。 So what should I return? 那我应该退货吗? and address? 和地址? If I use & the class does not compile. 如果我使用&类无法编译。

Ho to implement this class to not return a pointer to the local ´unsigned char array´? 如何实现此类以不返回指向本地“无符号字符数组”的指针?

ps: I am not using std::vector<unsigned char> or other types because it increases 10 time to return the value. ps:我没有使用std::vector<unsigned char>或其他类型,因为它增加了10次返回值的时间。 With char array I got 0.005 milliseconds and with std::vector<unsigned char> I got 0.07 milliseconds. 使用char数组,我得到0.005毫秒,而使用std::vector<unsigned char>我得到了0.07毫秒。

class SkinnyBuffer {
private:
    unsigned char* _value;
public:
    ~SkinnyBuffer();
    SkinnyBuffer();
    void setBufferValue(unsigned char value[]);
    unsigned char& getBufferValue();;
};

#include "utils/SkinnyBuffer.h"

SkinnyBuffer::~SkinnyBuffer() {
}
SkinnyBuffer::SkinnyBuffer() {
}
void SkinnyBuffer::setBufferValue(unsigned char value[]) {
    _value = value;
}
unsigned char SkinnyBuffer::getBufferValue() {
    return _value;
}

The question is a little underspecified but does open up some possibilities. 这个问题虽然有点不足,但确实提供了一些可能性。

First of all, you need to decide these things: 首先,您需要决定以下事项:

  • Do you want to store an array, or a pointer? 您要存储数组还是指针?
    • Currently you're storing a pointer, though it may point to an array. 当前,您正在存储一个指针,尽管它可能指向一个数组。
  • Do you want to return an array, or a pointer to its first element? 您是否要返回数组或指向其第一个元素的指针?
    • You can't return an array 你不能返回数组
    • You can return a pointer in this case (it's not UB, but getBufferValue needs to return a unsigned char* in order for this to compile), but do you want to? 在这种情况下,您可以返回一个指针(它不是UB,但是getBufferValue需要返回一个unsigned char*才能进行编译),但是您想要这样做吗?

If the bounds of the SkinnyBuffer can change, then storing a pointer to some dynamically allocated memory is appropriate. 如果SkinnyBuffer的界限可以更改,则存储指向一些动态分配的内存的指针是适当的。 You should instead use a std::vector for this purpose, and accessing a vector is not slower despite your claims — you must have accidentally copied it somewhere or done some other inefficient thing. 您应该为此目的而使用std::vector ,并且尽管有要求,访问向量也不会较慢-您必须不小心将其复制到某个地方或做了其他低效的事情。 So you can explore that further. 因此,您可以进一步探索。

As for returning values, well again this depends on what you want. 至于返回值,同样,这取决于您想要什么。 It may be more logical to implement an operator[] that provides element-like access to the buffer. 实现operator[]可能更合乎逻辑,该operator[]提供对缓冲区的类似元素的访问。 But, then, why wrap the vector at all? 但是,为什么还要包装向量呢? Just have a vector! 只需一个向量!

If you do want to return a pointer, you won't be able to assign this to an object of array type (despite what Robert's answer claims); 如果您确实想返回一个指针,则将无法将其分配给数组类型的对象(尽管Robert的回答是声明的)。 you'd have to use std::copy (or a related technique) to copy its elements one at a time. 您必须使用std::copy (或相关技术)一次复制一个元素。 This is a limitation inherited from C, which does not permit direct array assignment. 这是从C继承的限制,不允许直接分配数组。 Also note that the returned pointer will be "weak" but also not clearly describe this to the programmer writing code at the call site, which is dangerous; 还应注意,返回的指针将是“弱”的,但也不能向程序员在调用站点处编写代码的情况下清楚地描述这一点,这很危险; a smart pointer would make this better. 一个聪明的指针会使它变得更好。

Finally, the core of your problem is that this all applies to setBufferValue , too. 最后,您问题的核心是这一切也适用于setBufferValue Your input into the class just copies a pointer, and who knows what that points to? 您在类中的输入仅复制了一个指针,谁知道该指向什么? Again, a vector will make your life much easier. 同样,向量将使您的生活更加轻松。

Ultimately there are plenty of choices here and the "right" choice depends on your actual requirements and what you want to do with this data. 最终,这里有很多选择,“正确”的选择取决于您的实际需求以及您要对这些数据进行的处理。

This is a more reasonable approach. 这是一种更合理的方法。 Although, it is not good either. 虽然,这也不是一件好事。 You should implement the constructor and destructor. 您应该实现构造函数和析构函数。 The way to do it is to return a pointer. 这样做的方法是返回一个指针。 You can't return an entire array. 您不能返回整个数组。 Although you should keep an extra field for the size of the array. 尽管您应该为数组的大小保留一个额外的字段。

class SkinnyBuffer {
private:
    unsigned char* _value;
public:
    ~SkinnyBuffer();
    SkinnyBuffer();
    void setBufferValue(unsigned char value[], size_t n);
    unsigned char* getBufferValue();
};

// imagine this is the cpp file down here

void SkinnyBuffer::setBufferValue(unsigned char value[], size_t n) {
    if(_value != nullptr)
      delete [] _value;
    _size = n; // assume _size is a field
    _value = new unsigned char[_size];
    std::copy(value, value + n, _value);
}

unsigned char* SkinnyBuffer::getBufferValue() {
    return _value;
}

First of all, your setBufferValue will set _value to point to the same address of the passed array. 首先,您的setBufferValue将设置_value指向传递的数组的相同地址。 It will not copy it, so be careful dealing with it 它不会复制它,因此请小心处理

Now, for getBufferValue , it must be declared as: 现在,对于getBufferValue ,必须将其声明为:

unsigned char * getBufferValue();

and

unsigned char * SkinnyBuffer::getBufferValue() {

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM