使用CLI传输指针值时出错

时间:2013-08-26 14:31:55

标签: c++ pointers c++-cli

我正在尝试制作一个非常虚拟的程序,我在准备中插入值并在搜索中搜索。我是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();
    }
}

2 个答案:

答案 0 :(得分:2)

您忘了分配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...
};

答案 1 :(得分:1)

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

编辑:如果您打算以这种方式使用它,为什么不使用指针呢?此外,您可以简单地使用向量并在函数的开头清除它,无论如何都会改变它的内容。

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

这就是你的代码应该是这样的:

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;
}

OR

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);
    }
}

编辑:正如Hans所说,你没有在包装器中为你的b指针指定任何东西。检查他的答案以获取更多细节。