全局数组变量在线程中丢失值

时间:2015-02-19 15:31:30

标签: c++

我正在开发一个小应用程序,它首先将一些值添加到定义为全局变量的指针数组中:

#define MAX_LOCATIONS 32

LocationDTO* locations[MAX_LOCATIONS];
int nLocations = 0;

我使用以下方法将LocationDTO对象引用添加到数组中:

bool addLocation(Location *location, string name){
    LocationDTO l(name, location);
    if(nLocations < MAX_LOCATIONS){
        locations[nLocations] = &l;
        nLocations++;
        return true;
    }else{
        return false;
    }
}

我用这种方式从main方法调用这个函数:

Location l1(1,2);
addLocation(&l1, "one");

Location l2(2,3);
addLocation(&l2, "two");

Location l3(4,5);
addLocation(&l3, "three");

添加所有值后,我启动一个将处理此数组的线程。线程定义:

void* server_thread(void* args){
    // Some code

    int i;
    for(i=0; i < nLocations; i++){
        LocationDTO* l = locations[i];

        // More Code
    }
} 

问题在于,在线程的这一点上,locations中包含的对象不再具有我分配给它们的值。

是否会发生此问题,因为我在addLocation中创建对象,然后在数组中保存引用?

4 个答案:

答案 0 :(得分:2)

是的,你是对的。当你离开addLocation方法时,LocationDTO l变量将被销毁。

我发现此问题的解决方案很少: 第一个解决方案:

std::vector<LocationDTO> locations;
const size_t maxSize = 32;
bool addLocation(Location *location, string name)
{
    if( locations.size() < maxSize )
    {
        locations.emplace_back( name, location );
        return true;
    }
    return false;
}

第二个解决方案:

bool addLocation(Location *location, string name){
    LocationDTO* l = new LocationDTO(name, location);
    if(nLocations < MAX_LOCATIONS){
        locations[nLocations] = l;
        nLocations++;
        return true;
    }else{
        return false;
    }
}

如果您决定使用第二个解决方案,请不要忘记删除所有已分配的LocationDTO对象

答案 1 :(得分:0)

addLocation中,您要创建一个局部变量l,并将l的地址存储在全局数组中。在addLocation结束时,addLocation中的任何局部变量在被销毁时都会变为无效。曾经l的地址处的内存可以用于其他数据。您必须使用某种形式的动态内存分配,以允许该位置的内存超出addLocation函数的范围。

答案 2 :(得分:0)

似乎您在堆栈上创建这些对象并将指针传递给addLocation()方法。离开示波器(退出功能)时会破坏这些对象。你确定在启动线程时是否存在这些对象?

试试这个:

addLocation(new Location(1,2), "one");
addLocation(new Location(2,3), "two");
addLocation(new Location(4,5), "three");

当然你必须在以后销毁这些物品。

答案 3 :(得分:0)

  

问题是,在线程的这一点上,位置内包含的对象不再具有我分配给它们的值。

您的locations数组不包含LocationDTO个对象。它包含指针到对象。

  

是否会发生此问题,因为我在addLocation中创建对象,然后在数组中保存引用?

是的,差不多。更确切地说,您的错误是您将locations中的指针指向自动变量。当自动变量超出范围时(在这种情况下在addLocation的末尾),自动变量被销毁,之后指针不再指向有效对象。引用与指针不同,但这也适用于它们。

避免内存处理错误的最简单方法是让标准库来处理它。我建议你使用std::vector<LocationDTO> locations;