【问题标题】:Linked list with GMP variables带有 GMP 变量的链表
【发布时间】:2016-07-08 21:38:45
【问题描述】:

我正在尝试实现一个链表,其中包含一个合理的 GMP 数组 mpq_t 作为其数据,此外,我希望它保持当前链表末尾的长度 lte 并为方便起见数组n

为了对其进行测试,我生成了任意的 mpq_t 数组并将其输入到我的 GMPlist_push 函数中,该函数旨在创建一个保存该数组的新节点。

下面的代码可以运行,但是要么我忘记了一些琐碎的事情,要么我的 GMP 安装有问题。当我运行它时,它应该输出 5 个随机数,然后告诉我它在哪个节点中,但是在我的 MacBook 上它是 1、4294967297、4294967298、4294967297,然后它继续在两者之间振荡,当我运行在我的 Debian 桌面上完全相同的代码它执行所需的 1,2,3...

这似乎是“不可预测”的行为,在 Linux 机器上似乎对我有利,但在我的 Mac 上却不行。你能看到我忘记的东西吗?你还能重现错误的行为吗?

可能值得注意的是,尽管可执行文件运行时没有错误,但 lldb 会因不明确的 malloc 错误而崩溃。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <gmp.h>
#include <assert.h>

struct GMPlist {
    mpq_t* data;
    size_t n, lte;
    struct GMPlist* next;
};

typedef struct GMPlist GMPlist;

mpq_t *randomVector(size_t n){
    mpq_t* retVal;
    retVal = malloc(n*sizeof(*retVal));
    size_t i;
    size_t den,num;
    for (i = 0; i < n; i++){
        mpq_init(retVal[i]);
        den = (size_t)rand();
        num = (size_t)rand();
        mpq_set_ui(retVal[i],den,num);
        mpq_canonicalize(retVal[i]);
    }
    return retVal;
}


void GMPlist_push(GMPlist** elem, mpq_t* data){
    GMPlist* nextElem = malloc(sizeof(GMPlist*));

    nextElem->next = *elem;
    nextElem->lte = (*elem)->lte + 1;
    nextElem->n = (*elem)->n;

    nextElem->data = data;
    *elem = nextElem;
}

int main(int argc, char const *argv[])
{
    GMPlist* elem = malloc(sizeof(GMPlist));


    srand(time(NULL));

    elem->next = NULL;
    elem->lte = 0;
    elem->n = 5;
    mpq_t* tester;
    size_t i,j;

    for (j = 0; j<10; j++){
        tester = randomVector(5);

        GMPlist_push(&elem, tester);

        for (i=0; i<5; i++){
            mpq_out_str(stdout,10,elem->data[i]);
            fprintf(stdout, " ");
        }
        fprintf(stdout, ", %lu\n", elem->lte );
    }
return 0;
}

谢谢你, 雷纳

【问题讨论】:

    标签: c linked-list gmp


    【解决方案1】:

    GMPlist_push 中,您没有分配适当的内存量:

    GMPlist* nextElem = malloc(sizeof(GMPlist*));
    

    您想要GMPlist 的大小,但您得到的是GMPlist * 的大小,后者更小。

    改为这样做:

    GMPlist* nextElem = malloc(sizeof(GMPlist));
    

    如果您在valgrind 下运行代码,它将显示您在哪里读/写了您不应该读/写的内存。

    【讨论】:

    • 你的回答解决了问题!谢谢! Valgrind 和 GMP 不能很好地协同工作,这是 GMP 的已知问题之一。 Click
    猜你喜欢
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 1970-01-01
    相关资源
    最近更新 更多