GMP的分段错误

时间:2015-02-26 16:22:11

标签: c++ floating-point precision gmp

我有一个程序从文件中读取矩阵并将其存储在变量basis_MP中,这是一个实例变量。由于从文件中读取的值非常大(不适合本机数据类型),因此我使用GMP获得更高的精度。我打印存储文件的矩阵的值,它们是正确的。

在读取文件后,我还初始化了一些其他也使用GMP的辅助变量。我将它们声明为实例变量,因为我不想在每次调用其他方法时分配和释放它们。一旦初始化第一个代码行的代码被执行,我就会出现分段错误。

basis.h:

#ifndef BASIS_H
#define BASIS_H

#include <math.h>
#include <gmp.h>

using namespace std;

class Basis {

private:

    int rank; //No. vectors in the basis (also called n)
    int dimension; //Dimension of each vector in the basis (also called m)
    mpz_t **basis_MP;  //Matrix containing all the vectors in the basis

    mpf_t aux_MP_f0;
    mpf_t aux_MP_f1;
    mpf_t aux_MP_f2;

public:

    Basis(); //Empty constructor
    Basis(char *filename); //Constructor from file
}

basis_MP是矩阵被放置的变量,而aux_MP_f0aux_MP_f1aux_MP_f2是3个辅助变量。所有这些都使用GMP以获得更高的精度。在构造函数Basis(char *filename)中,初始化所有这些变量并读取矩阵。

basis.cpp:

#include "basis.h"

Basis::Basis() // Empty constructor
{

}

Basis::Basis(char* filename) // Constructor from file
{
    char delim[] = " \n[]";

    ifstream stream;
    stream.open(filename);
    if(!stream) cerr << "File was not read" << endl;

    stream.seekg (0, stream.end);
    int length = stream.tellg();
    stream.seekg (0, stream.beg);

    char * buffer = new char [length];
    char * number = new char [length];

    std::cout << "Reading " << length << " characters... " << endl;
    stream.read (buffer,length);

    int count = 0;
    for (int i = 0; i < length; i++){
        if (buffer[i] == '\n') {
            count++;
            break;
        }
        if (buffer[i] == ' ') {
            count++;
        }
    }

    dimension = count;
    rank = count;

    basis_MP = (mpz_t**)malloc(rank*sizeof(mpz_t*));
    for (int i = 0; i < rank; i++)
        basis_MP[i] = (mpz_t*)malloc(dimension*sizeof(mpz_t));

    number = strtok(buffer, delim);

    for (int i = 0; i < rank; i++) {
        for (int j = 0; j < dimension; j++) {
            mpz_init_set_str(basis_MP[i][j], number, 10);
            number = strtok(NULL, delim);
        }
    }

    stream.close();

    mpf_init2(aux_MP_f0, mpz_sizeinbase(basis_MP[0][0], 2));
    mpf_init2(aux_MP_f1, mpz_sizeinbase(basis_MP[0][0], 2));
    mpf_init2(aux_MP_f2, mpz_sizeinbase(basis_MP[0][0], 2));

    delete buffer;
    delete number;
}

辅助变量用矩阵的第一个向量的精度初始化。分段错误发生在这一行:mpf_init2(aux_MP_f0, mpz_sizeinbase(basis_MP[0][0], 2));

main.cpp中:

#include "basis.h"

int main (int argc, char **argv) {
    Basis *b = new Basis(argv[1]);
}

我得到的错误如下:

Program received signal SIGSEGV, Segmentation fault.
_int_malloc (av=0x7ffff7114760 <main_arena>, bytes=144) at malloc.c:3489
3489    malloc.c: No such file or directory.

从gdb输出回溯:

(gdb) bt
#0  _int_malloc (av=0x7ffff7114760 <main_arena>, bytes=144) at malloc.c:3489
#1  0x00007ffff6dd92f0 in __GI___libc_malloc (bytes=144) at malloc.c:2891
#2  0x00007ffff7b71829 in __gmp_default_allocate () from /home/fcorreia/install/gmpxx/lib/libgmp.so.10
#3  0x00007ffff7b721db in __gmpf_init2 () from /home/fcorreia/install/gmpxx/lib/libgmp.so.10
#4  0x000000000040208f in Basis::Basis (this=0x607010, filename=0x7fffffffea8c "/home/project/dim10.txt") at src/basis.cpp:55
#5  0x000000000040517b in main (argc=2, argv=0x7fffffffe818) at src/main.cpp:4

我也尝试用mpf_init替换mpf_init2并得到以下错误:

*** Error in `/home/project/a.out': malloc(): memory corruption: 0x0000000000608080 ***

Program received signal SIGABRT, Aborted.
0x00007ffff6d8ce37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
    56  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.

相应的回溯:

(gdb) bt
#0  0x00007ffff6d8ce37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff6d8e528 in __GI_abort () at abort.c:89
#2  0x00007ffff6dceb04 in __libc_message (do_abort=1, fmt=fmt@entry=0x7ffff6ed7a80 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ffff6dd829b in malloc_printerr (ptr=0x608080, str=0x7ffff6ed3bda "malloc(): memory corruption", action=<optimized out>) at malloc.c:4996
#4  _int_malloc (av=0x7ffff7114760 <main_arena>, bytes=24) at malloc.c:3447
#5  0x00007ffff6dd92f0 in __GI___libc_malloc (bytes=24) at malloc.c:2891
#6  0x00007ffff7b71829 in __gmp_default_allocate () from /home/install/gmpxx/lib/libgmp.so.10
#7  0x00007ffff7b72190 in __gmpf_init () from /home/install/gmpxx/lib/libgmp.so.10
#8  0x00000000004020fc in Basis::Basis (this=0x608010, filename=0x7fffffffea8c "/home/project/dim10.txt") at src/basis.cpp:55
#9  0x0000000000405219 in main (argc=2, argv=0x7fffffffe818) at src/main.cpp:4

某处内存已被破坏,我无法弄清楚在哪里。可能,我没有正确使用gmp。有没有人有一些提示?

由于

0 个答案:

没有答案