C++ munmap_chunk:使用std::vector更改数据存储位置时指针无效

C++ munmap_chunk:使用std::vector更改数据存储位置时指针无效,c++,c++11,vector,C++,C++11,Vector,我正在为一个微控制器编写一个程序,我需要将一个向量的数据分配到内存中的一个特定位置(存储在闪存中) 他在退出main()函数时出错,因为他无法释放vector2 为什么呢?我怎样才能解决这个问题? 有更好的办法吗 另外,我可以将向量的指针(元值)保存在RAM中,如果这样更好的话,还可以将它们写入flash。使用Flash是因为我的RAM有限,并且这些向量只有在从外部加载新模型时才会写入。有许多事情看起来很可怕,我为我的直截了当表示歉意,但我在这里真正指的是“可怕” 这完全是错误的。您正在分配一个

我正在为一个微控制器编写一个程序,我需要将一个向量的数据分配到内存中的一个特定位置(存储在闪存中)

他在退出main()函数时出错,因为他无法释放vector2

为什么呢?我怎样才能解决这个问题? 有更好的办法吗


另外,我可以将向量的指针(元值)保存在RAM中,如果这样更好的话,还可以将它们写入flash。使用Flash是因为我的RAM有限,并且这些向量只有在从外部加载新模型时才会写入。

有许多事情看起来很可怕,我为我的直截了当表示歉意,但我在这里真正指的是“可怕”

这完全是错误的。您正在分配一个字节来存储内部的向量,期望对象存储10个字节,但实际上没有为底层数组分配空间

简言之,我认为你已经到达了一个句号。您试图解决的问题是“如何使
std::vector
从闪存分配内存”

通常解决此类问题的方法是使用自定义分配器

template<typename T>
struct allocator {
    typedef size_t size_type; 
    typedef ptrdiff_t difference_type;
    typedef T * pointer;
    typedef T const& const_pointer;
    typedef T& reference;
    typedef T const& const_reference;
    typedef T value_type;
    pointer allocate(size_t size) {
        void * mem = micro_controller_api::allocate_flash_memory(size); //I don't know what your API looks like

        //You'll need something else if you're not able to throw exceptions in your code.
        if(!mem) throw std::bad_alloc(); 

        //On its own, this would be unsafe, but std::vector uses placement new with its memory,
        //so you don't need to worry that the cast here would risk some undefined behavior.
        return static_cast<pointer>(mem);
    }
    void deallocate(pointer p, size_t) noexcept { micro_controller_api::free_flash_memory(static_cast<void*>(p)); }

    allocator() = default;
    template<typename U>
    allocator(allocator<U> const&) {}

    pointer address(reference r) const {return addressof(r);}
    const_pointer address(const_reference r) const {return addressof(r);}

    bool operator==(allocator const&) const {return true;} //All allocators are the same
    bool operator!=(allocator const&) const {return false;}
};

int main() {
    std::vector<struct_gauss, allocator<struct_gauss>> vector1(10);
    std::vector<struct_gauss, allocator<struct_gauss>> vector2(10);
    //Do whatever; vector1 and vector2 are, as far as anyone is concerned, perfectly valid vectors
}
模板
结构分配器{
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T*指针;
typedef T const&const_指针;
typedef T&reference;
类型定义T常数和常数参考;
类型定义T值_类型;
指针分配(大小\u t大小){
void*mem=micro\u controller\u api::allocate\u flash\u memory(size);//我不知道你的api是什么样子
//如果您不能在代码中抛出异常,那么您将需要其他东西。
如果(!mem)抛出std::bad_alloc();
//就其本身而言,这是不安全的,但std::vector使用内存中的新位置,
//所以你不必担心这里的演员可能会有一些未定义的行为。
返回静态_-cast(mem);
}
无效解除分配(指针p,大小t)noexcept{micro_controller_api::free_flash_memory(静态_cast(p));}
分配器()=默认值;
模板
分配器(分配器常数&){}
指针地址(引用r)常量{返回地址(r);}
常量指针地址(常量引用r)常量{返回地址(r);}
bool运算符==(分配器常量&)常量{return true;}//所有分配器都相同
布尔运算符!=(分配器常量&)常量{返回false;}
};
int main(){
std::矢量1(10);
std::矢量2(10);
//做任何事;就任何人而言,向量1和向量2都是完全有效的向量
}

请注意,我自己以前没有编写过分配器,我在这里提供的分配器是基于a上显示的模板的,(编辑:我还通过引用添加了一些内容),所以我可能犯了错误。但希望所有这些都足以解决您的问题。

据我所知,这从头到尾都是完全错误的。可能您正在寻找的是分配器。您不能完全破坏vector对象的内存,并期望它在以后仍能正常工作。代码似乎采用了
std::vector
的内部结构。有趣的是,它在MSVC、GCC和clang上适用于1向量的情况,但它似乎到处都是未定义的行为。感谢您明确的回答。我知道我正在以一种可怕的方式攻击std::vector。但是,我不知道如何分配特定的内存地址。据我所知,没有用于闪存分配的API(没有一个来自供应商的例子)(我使用的是来自硅实验室的EFM32奇迹壁虎)预先分配内存,他们希望它们不会交叉到程序内存中,而且我也不知道如何在标准C++中在特定的地址分配一些内存。
address of vector2 begin = 0xf42c70    
vector1[9].mean = 10; vector2[0].mean = 5                                                                                                                                    
*** Error in `/home/a.out': munmap_chunk(): invalid pointer: 0x0000000000f42c70 ***                                                                           
Aborted 
std::vector<struct_gauss> makeVector(size_t size, void* address, void* &endAddress) {
    std::vector<struct_gauss> dummy;
    struct_gauss **dummyPointer = (struct_gauss **) &dummy; // Address to metavalue of std::vector dummy (exists of 3 pointers)
    *dummyPointer = (struct_gauss *) address; // Point data of dummy to requested address
    *(dummyPointer+1) = ((*dummyPointer)+size);
    *(dummyPointer+2) = *(dummyPointer+1);
    endAddress = (void*) &(*dummy.end());
    return dummy;
}
int main()
{
    void* dummyPointer1 = malloc(1);
    void* dummyPointer2;
    auto vector1 = makeVector(10, (void*) dummyPointer1, dummyPointer2);
    auto vector2 = makeVector(10, (void*) dummyPointer2, dummyPointer2);
template<typename T>
struct allocator {
    typedef size_t size_type; 
    typedef ptrdiff_t difference_type;
    typedef T * pointer;
    typedef T const& const_pointer;
    typedef T& reference;
    typedef T const& const_reference;
    typedef T value_type;
    pointer allocate(size_t size) {
        void * mem = micro_controller_api::allocate_flash_memory(size); //I don't know what your API looks like

        //You'll need something else if you're not able to throw exceptions in your code.
        if(!mem) throw std::bad_alloc(); 

        //On its own, this would be unsafe, but std::vector uses placement new with its memory,
        //so you don't need to worry that the cast here would risk some undefined behavior.
        return static_cast<pointer>(mem);
    }
    void deallocate(pointer p, size_t) noexcept { micro_controller_api::free_flash_memory(static_cast<void*>(p)); }

    allocator() = default;
    template<typename U>
    allocator(allocator<U> const&) {}

    pointer address(reference r) const {return addressof(r);}
    const_pointer address(const_reference r) const {return addressof(r);}

    bool operator==(allocator const&) const {return true;} //All allocators are the same
    bool operator!=(allocator const&) const {return false;}
};

int main() {
    std::vector<struct_gauss, allocator<struct_gauss>> vector1(10);
    std::vector<struct_gauss, allocator<struct_gauss>> vector2(10);
    //Do whatever; vector1 and vector2 are, as far as anyone is concerned, perfectly valid vectors
}