将指向vector中元素的指针设置为null,然后检查指针是否为null(C ++)

时间:2013-08-04 20:28:00

标签: c++ null stdvector

我想将指向vector数组中某些元素的指针设置为NULL(基于条件),然后检查元素指针是否为NULL。如果指向该元素的指针为NULL,则从向量数组中删除该元素。

我的编译器给了我一个错误,说地址表达式必须是左值或函数指示符,我不明白为什么(行位置在代码中注释)。由于我使用&获取值的地址,我是否看不到指向该元素的指针是否为NULL?

我包含了前面的代码,因为错误可能就在那里,

相关代码:

vector<particle> pl = c.particlelist;
vector<particle> noncollision = c.particlelist;
vector<vector<particle>> collisionlist = new vector<vector<particle>>();
for (int i = 0; i < c.numparticles-1; i++){
    particle first = pl[i];
    for (int j = i+1; j < c.numparticles; j++)
    {
        particle second  = pl[j];
        double d = distance(first, second);
        if (d==0)
        {
            vector<particle> temp = {pl[i], pl[j]};
    collisionlist.push_back(temp);
            noncollision[i].setxposint(NULL); 
            noncollision[j].setxposint(NULL);
        }
        else
        {
        }
    }
}
int j = 0;
for (int i = 0; i < noncollision.size(); i++)
{
    if (&(noncollision[i].getxpos()) == NULL) ////// ERROR HERE
    {
        noncollision.erase(noncollision.begin()+i);
    }
    else
    {
        j++;
    }
}

我是C ++的新手,如果你可以建议一个更优雅的方式来做这个或修复,那将非常感激。我还假设我设置指向元素noncollision[i].setxposint(NULL);的指针的方法是正确的吗?我可以使用函数返回一个整数,并取地址吗?

getxpos和setxposint的函数:

int particle::getxpos(){
return xpos;
}

void particle::setxposint(int b){
xpos = b;
}

5 个答案:

答案 0 :(得分:3)

您正在使用&获取指向临时值的指针(从getxpos返回),这是不允许的;由于临时将会消失,因此该地址不会以任何方式使用,因此语言不允许。即使你能得到它的地址,它肯定也不会是NULL。

答案 1 :(得分:2)

noncollision[i].setxposint(NULL);

该行正在进行的是将xpos设置为零。通常,术语NULL与指针一起使用,0与整数一起使用。 NULL通常是0L的宏。

&(noncollision[i].getxpos()) == NULL

这是做什么的,这是不正确的,是试图从成员方法getxpos()获取返回值的地址,并将其与NULL进行比较。而你真正想做的只是看看函数是否返回零。所以只需将此行更改为:

noncollision[i].getxpos() == 0

答案 2 :(得分:2)

我将解释为什么编译器不理解你的意思。

写作时

&(someFunction())

您要求函数返回的地址。但函数返回值。值没有地址。变量有地址。

当某些内容是一个内存字(包含一个值)时,它可以用作左值(左值),因为你可以将内容放入内存中:< / p>

int b = 1; //make room for an `int` on the stack, then put a `1` there.

当某些东西只是一个值时,它只能用作 rvalue 。以下内容无法编译,原因与您的代码不相同:

int b; //make room for an `int` on the stack.
42 = b; //ERROR, this makes no sense.
if (42 == NULL) { std::cout << "this is never true" << std::endl; }
&42; //ERROR, 42 isn't a piece of memory, it's a value.

(警告:您可以使用值来引用内存中的单词:此用法称为指针,例如

int b = 1;
*((int *)(42)) = b;

意思是“将b的值放入具有地址42 的内存。这编译得很好(但如果你不允许写入,则会崩溃)记忆在42。)

答案 3 :(得分:1)

您似乎正在尝试检查碰撞点对。然后,您可以记录每个点是否有任何碰撞。这最好由一个简单的标志列表来处理:

std::vector<bool> has_collision(c.numparticles, false); // init: no collisions found

然后:

    if (d==0)
    {
        has_collision[i] = true;
        has_collision[j] = true;
    }

最后,遍历标志列表并获得没有冲突的点:

for (size_t i = 0; i < c.numparticles; ++i)
{
    if (!has_collision[i])
    {
        // whatever
        // possibly push_back pl[i] into some list
    }
}

此外:使用vector来保持一对(i,j)点是令人困惑的。标准库具有std::pair类型,用于此目的。

另外:您不需要显式动态分配(new);让标准库以安全,无混淆的方式为您管理内存。而不是

vector<vector<particle>> collisionlist = *new vector<vector<particle>>();

使用

vector<vector<particle>> collisionlist;

(或vector<pair<particle, particle>>,如上所述。)

答案 4 :(得分:1)

在我看来,您正在尝试跟踪“已访问”的项目,而不确定究竟是哪种方式。

您可以使用“外部”标记,而不是“修改”项目。一套看起来很好。您可以在粒子列表中使用一组iterator,或者在这种情况下使用一组可能更稳定的indicesij)。 / p>

这是一个开始:

#include <vector>
#include <set>

struct particle { };

double distance(particle const&, particle const&) { return 1.0; }

struct context
{
    std::size_t numparticles;
    std::vector<particle> particlelist;

    context() : numparticles(100), particlelist(numparticles) {}
};

static context c;

int main()
{
    using std::vector;
    using std::size_t;

    vector<particle> pl = c.particlelist;
    vector<vector<particle>> collisionlist;

    std::set<size_t> collision;

    for(size_t i = 0; i < c.numparticles-1; i++)
    {
        particle first = pl[i];
        for(size_t j = i+1; j < c.numparticles; j++)
        {
            particle second  = pl[j];
            double d = distance(first, second);
            if(d < 0.0001)
            {
                collisionlist.push_back({pl[i], pl[j]});
                collision.insert(i);
                collision.insert(j);
            }
            else
            {
            }
        }
    }

    for(size_t i = 0; i < pl.size(); i++)
    {
        if(collision.end() != collision.find(i))
        {
            // do something
        }
    }

    // alternatively
    for (int index : collision)
    {
        particle& p = pl[index];
        // do something
    }
}

注意非常警惕 浮点比较 ,如

 if (d==0.0) // uhoh

因为它可能无法达到您的预期