使用CLI传输指针值时出错

Error when transfering the value of a pointer, using CLI

本文关键字:出错 指针 CLI 传输 使用      更新时间:2023-10-16

我正在尝试制作一个非常伪的程序,在其中插入prepare中的值,并在搜索中插入search。我对C++很陌生,我只是想学习一些语言的概念。当我尝试vector = *v时,我收到一个错误:尝试读取或写入受保护的内存。这通常表示其他内存已损坏我正在使用vc++进行一个c++/cli实验。

我做错了什么?

#include "stdafx.h"
#include <algorithm>
#include <vector>
#include <ostream>
#include <iostream>
#pragma once
class BinarySearch
{
public:
    BinarySearch(void)
    {
    }
    virtual ~BinarySearch(void)
    {
    }
    int search(int key)
    {
         std::vector<int>::iterator low,up;
         low=std::lower_bound (vector.begin(), vector.end(), key); 
         return low - vector.begin();
    }
    std::vector<int> vector;
    void prepare(void)
    {
        std::vector<int>* v = 
            new std::vector<int>();
        int max = std::pow(33, 3);
        for(int i=0; i < max; i++) {
            v->push_back(i);
        }
        vector = *v;
    }
};

搜索之前使用prepare方法。

包装器,它调用c++中的代码:

namespace Native {
    public ref class Wrapper
    {
    public:
        Wrapper(void)
        {
        }
        BinarySearch* b;
        void Prepare(void)
        {
            b->prepare();       
        }
        int Search(int i)
        {
            return b->search(i);
        }
    };
}

c#:中的呼叫者

class Program
{
    static void Main(string[] args)
    {
        var w = new Wrapper();
        w.Prepare();
        var position = w.Search(12);
        Console.WriteLine("Array.BinarySearch p: {0}", position);
        Console.ReadLine();
    }
}

您刚刚忘记分配b指针。因此,当您在Prepare()包装方法中取消引用代码时,代码当然会崩溃。只需在构造函数中创建BinarySearch类的一个实例。

您还需要确保本机对象再次被销毁。实现析构函数和终结器,这样即使C#代码没有处理对象,也能保证做到这一点。像这样:

public ref class Wrapper 
{
private:
    BinarySearch* b;
public:
    Wrapper(void) : b(new BinarySearch) {}
    ~Wrapper() { delete b; b = nullptr; }
    !Wrapper() { this->~Wrapper(); }
    void Prepare(void) {
        if (b == nullptr) throw gcnew ObjectDisposedException("Wrapper");
        b->prepare();       
    }
    // etc...
};

您必须删除使用new创建的向量。线向量=*v只是复制另一个向量中的数据。换句话说,内存泄漏!所以之后调用delete v。

编辑:如果你打算这样使用指针,为什么不直接使用呢?此外,您可以简单地使用向量,并在函数开始时清除它,该函数无论如何都会更改其内容。

如果您确实需要一个指针,请首先将成员变量声明为指针,确保初始化为NULL,在调用prepare时,删除指针,然后将创建的新向量分配给新向量。请注意,对NULL指针调用delete会导致noop(无操作)。尽管在这一点上。。。您可能只想在构造函数中调用new一次,在析构函数中调用delete。您只需要在准备清除内容时调用clear即可。

这就是你的代码应该是什么样子:

std::vector<int> vector;
void prepare(void)
{
    std::vector<int>* v = 
    new std::vector<int>();
    int max = std::pow(33, 3);
    for(int i=0; i < max; i++) {
        v->push_back(i);
    vector = *v;
    delete v;
}

std::vector<int> vector;
void prepare(void)
{
    vector.clear();
    int max = std::pow(33, 3);
    for(int i=0; i < max; i++) {
        vector.push_back(i);
    }
}

编辑:正如汉斯所说,你没有在包装器中为你的b指针分配任何东西。查看他的回答以了解更多详细信息。