使用指针从函数中获取值(c ++)

时间:2009-08-24 20:54:11

标签: c++ function pointers

我有一个计算几个不同值的函数:

int ASPfile::get_dimensions(int* Lat, int* Lon, 
        vector<double>* Latgrid, vector<double>* Longrid) {

    _latsize = get_latsize();
    _lonsize = get_lonsize();

    Lat = &_latsize;
    Lon = &_lonsize;

    latgrid = read_latgrid();
    longrid = read_longrid();

    *Latgrid = latgrid;
    *Longrid = longrid;

    return 0;
}

此函数调用如下:

int* Latsize = NULL;
int* Lonsize = NULL;
vector<double>* Latgrid = NULL;
vector<double>* Longrid = NULL;
int res = asp->get_dimensions(Latsize,Lonsize,Latgrid,Longrid);

然后,我尝试按如下方式访问值:

cout << (*Szagrid)[4];

或者像这样

cout << Szagrid->at(4);

该程序编译时没有任何警告。但是,当我尝试访问get_dimensions()应该“填充”的指针时, valgrind告诉我以下内容:

==10531== Invalid read of size 8
==10531==    at 0x633D5DA: std::vector<double, std::allocator<double> >::operator=(std::vector<double, std::allocator<double> > const&) (in /home/myhome/src/libiup/Release/libiup.so)
==10531==    by 0x633CADC: ASPfile::get_dimensions(int*, int*, int*, std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*) (in /home/myhome/src/libiup/Release/libiup.so)
==10531==    by 0x41B90B: ASPfileTest::test_get_dimensions() (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==    by 0x41BACC: ASPfileTest::operator()() (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==    by 0x41E229: boost::function0<void>::operator()() const (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==    by 0x41E7C2: cute::runner<cute::eclipse_listener>::runit(cute::test const&) (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==    by 0x41D26A: runSuite() (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==    by 0x41DBC4: main (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==10531== 
==10531== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==10531==  Access not within mapped region at address 0x0
==10531==    at 0x633D5DA: std::vector<double, std::allocator<double> >::operator=(std::vector<double, std::allocator<double> > const&) (in /home/myhome/src/libiup/Release/libiup.so)
==10531==    by 0x633CADC: ASPfile::get_dimensions(int*, int*, int*, std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*, std::vector<double, std::allocator<double> >*) (in /home/myhome/src/libiup/Release/libiup.so)
==10531==    by 0x41B90B: ASPfileTest::test_get_dimensions() (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==    by 0x41BACC: ASPfileTest::operator()() (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==    by 0x41E229: boost::function0<void>::operator()() const (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==    by 0x41E7C2: cute::runner<cute::eclipse_listener>::runit(cute::test const&) (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==    by 0x41D26A: runSuite() (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==    by 0x41DBC4: main (in /home/myhome/src/libiup_test/Release/libiup_test)
==10531==  If you believe this happened as a result of a stack overflow in your
==10531==  program's main thread (unlikely but possible), you can try to increase
==10531==  the size of the main thread stack using the --main-stacksize= flag.
==10531==  The main thread stack size used in this run was 8388608.

我不太明白我做错了什么;可能是显而易见的事情,但我似乎无法找到问题。

非常感谢任何帮助!

5 个答案:

答案 0 :(得分:5)

你在get_dimensions中写入内存,但你实际上并没有真正分配内存。相反,您只是传递NULL指针。

一个可能的解决方法是将您的主叫代码更改为:

int Latsize, Lonsize;
vector<double> Latgrid;
vector<double> Longrid;
int res = asp->get_dimensions(&Latsize,&Lonsize,&Latgrid,&Longrid);

这会自动在堆栈上为变量分配空间,然后将分配的空间的地址传递给get_dimensions,这将修改值。

答案 1 :(得分:5)

你的问题得到了其他人的好评,但是我想指出,既然这是C ++,而不是C,如果你只是使用引用而不是指针,那么所有这些混乱都可以避免。这通常是你应该在这种情况下做的事情(如果不需要NULL返回值)

int ASPfile::get_dimensions(int& Lat, int& Lon, 
        vector<double>& Latgrid, vector<double>& Longrid) {

    Lat = get_latsize();
    Lon = get_lonsize();

    Latgrid = read_latgrid();
    Longrid = read_longrid();

    return 0;
}

// Call like this

int Latsize;
int Lonsize;
vector<double> Latgrid;
vector<double> Longrid;
int res = asp->get_dimensions(Latsize,Lonsize,Latgrid,Longrid);

答案 2 :(得分:3)

函数的签名指向我的信号我可能也会传递NULL指针,如果我手头没有适合的对象或者我对特定结果不感兴趣。但是,您的函数不会检查此函数并愉快地写入地址0

如果必须将正确的对象传递给函数,那么为什么不使用引用而不是指针?它们旨在用于您想要做的事情,更容易理解,更难以出错。

int ASPfile::get_dimensions( int& Lat
                           , int& Lon
                           , vector<double>& Latgrid
                           , vector<double>& Longrid );

答案 3 :(得分:1)

latgrid”和“longrid”定义在哪里?如果它们是ASPFile :: get_dimensions的本地,那么它们的析构函数将在函数返回时被调用,从而销毁它们。

答案 4 :(得分:0)

同意所有关于指针的说法。作为一个经验法则 - 除非你真的需要,否则不要使用它们。 与此同时,这里使用的模式看起来凌乱而丑陋,并且对get_dimensions函数的需求是完全模糊的。你正在增加不必要的复杂程度。

而不是这个,我怀疑你在ASPFile上的原型函数public中使用的那些get_和read_函数就足够了:

int Latsize = asp->get_latsize();
int Lonsize = asp->get_lonsize();
vector<double> Latgrid = asp->read_latgrid();
vector<double> Longrid = asp->read_longrid();

保持简单。