首页 > 解决方案 > 我正在尝试将一个 glogal 结构(trie_node)初始化为我的 main 函数中的头,并且遇到内存分配问题

问题描述

基本上,当我尝试在 main 中初始化它时,我从 valgrind 得到这个

==4262==    at 0x109730: main (in /home/raf/os/domaci4/main)
==4262==  Address 0x544c210 is 0 bytes after a block of size 464 alloc'd
==4262==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4262==    by 0x1096D3: main (in /home/raf/os/domaci4/main)
==4262== 
``` ```

typedef struct trie_node
{
    char c;
    int term;
    int subwords;
    struct trie_node *parent;
    struct trie_node *children[LETTERS];
}trie_node;

这是我将它写成全球性的方式 struct trie_node *head;

在这里我尝试分配内存并将所有内容设置为0。

    head = (trie_node*) malloc(sizeof(struct trie_node));
    head->term = 0;
    head->parent = NULL;
    head->subwords = 0;
    head->c = NULL;
    int i;
    for(i = 0; i < MAX_WORD_LEN; i++)
    {
        head->children[i] = NULL;
    }

我试图弄清楚到底是什么问题。任何帮助将非常感激!

==4810==    at 0x10974B: main (in /home/raf/os/domaci4/main)
==4810==  Address 0x544c568 is 0 bytes after a block of size 232 alloc'd
==4810==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4810==    by 0x1096EE: main (in /home/raf/os/domaci4/main)
==4810== 

valgrind: m_mallocfree.c:280 (mk_plain_bszB): Assertion 'bszB != 0' failed.
valgrind: This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.


host stacktrace:
==4810==    at 0x5804417A: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==4810==    by 0x58044294: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==4810==    by 0x58044419: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==4810==    by 0x580531AC: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==4810==    by 0x5800BA44: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==4810==    by 0x5800BC26: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==4810==    by 0x5809F705: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)
==4810==    by 0x580AECD0: ??? (in /usr/lib/valgrind/memcheck-amd64-linux)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 4810)
==4810==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4810==    by 0x50D918B: _IO_file_doallocate (filedoalloc.c:101)
==4810==    by 0x50E9378: _IO_doallocbuf (genops.c:365)
==4810==    by 0x50E8497: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:759)
==4810==    by 0x50E69EC: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1266)
==4810==    by 0x50DBA8E: puts (ioputs.c:40)
==4810==    by 0x10984D: main (in /home/raf/os/domaci4/main)

这是整个 valgrind 消息。

int main(int argc, char *argv[])
{
    char stopThread[10] = "\t";
    char add[10] = "_add_";
    char stop[10] = "_stop_";
    char file[50];
    char abs[100] = "/home/raf/os/domaci4/";
    char temp[100];
    char temp2[50];
    int j = 1;

    pthread_t thread1;
    pthread_t thread2;
    pthread_t thread3;
    pthread_t thread4;
    pthread_t thread5;

    head =  malloc(sizeof(trie_node));
    head->term = 0;
    head->parent = NULL;
    head->subwords = 0;
    head->c = NULL;
    int i;
    for(i = 0; i < MAX_WORD_LEN; i++)
    {
        head->children[i] = NULL;
    }



    char nesto[50];

    //char unos[50];
    char unos[200];
    while(1)
    {   
        //printf("Unesite komandu\n");
        scanf("%s", &unos);


        if(strcmp(unos, add) == 0){
            scanf("%s", &unos);
            strcpy(temp, unos);
            DIR *directory = NULL;

                //printf("Open success\n");
                /*
                if(j == 1){
                    pthread_create(&thread1, NULL, scanner_work, &temp);
                }
                j++;
                */
                //pthread_t threads[j] = (pthread_t*) malloc(sizeof(pthread_t));


                }

        /*
        if(strcmp(unos, stopThread) == 0){
            pthread_cancel(thread1);
        }
        */
        if(strcmp(unos, stop) == 0){
            printf("Izlaz iz sistema\n");
            break;
        }

    }
    return 0;


}

这是整个主要功能,但程序甚至无法启动。

标签: cstructmalloc

解决方案


您的代码片段没有足够的细节来说明真正的问题是什么。

但是,这里有一些我已经躺在那里的特里代码。它应该给你一些关于如何修复代码的想法:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>

#define LETTERS     26
typedef struct trie trie_t;
struct trie {
    int trie_let;                               // letter
    int trie_eow;                               // 1=end-of-word

    trie_t *trie_par;                           // pointer to parent
    trie_t *trie_cld[LETTERS];                  // children
};

trie_t *root;
#define TRIEPRT_MAX     10000
char trieprt_buf[TRIEPRT_MAX + 1];

// triefind -- find matching child trie based on id
trie_t *
triefind(trie_t *par,int let)
{
    int cldidx;
    trie_t *cld;
    trie_t *match;

    match = NULL;

    for (cldidx = 0;  cldidx < LETTERS;  ++cldidx) {
        cld = par->trie_cld[cldidx];

        // skip empty slot
        // NOTE: this will probably never happen based on trieattach
        if (cld == NULL)
            continue;

        if (cld->trie_let == let) {
            match = cld;
            break;
        }
    }

    return match;
}

// trienew -- get new trie
trie_t *
trienew(int let)
{
    trie_t *trie;

    trie = calloc(1,sizeof(trie_t));
    trie->trie_let = let;

    return trie;
}

// trieattach -- attach new child trie
trie_t *
trieattach(trie_t *par,int let)
{
    trie_t *cld;

    // allocate new trie
    cld = trienew(let);

    // cross-link parent and child
    cld->trie_par = par;
    par->trie_cld[let] = cld;

    return cld;
}

// triefindx -- find matching child trie (create new trie if none found)
trie_t *
triefindx(trie_t *par,int let)
{
    trie_t *cld;

    // find existing trie
    cld = triefind(par,let);

    // create new trie if it doesn't already exist
    if (cld == NULL)
        cld = trieattach(par,let);

    return cld;
}

// trieword -- add an entire word
void
trieword(const char *str)
{
    int chr;
    trie_t *trie;
    int nxt;

    trie = root;
    for (chr = *str++;  chr != 0;  chr = nxt) {
        nxt = *str++;

        chr = toupper(chr);

        trie = triefindx(trie,chr - 'A');

        // mark end-of-word
        if (nxt == 0)
            trie->trie_eow = 1;
    }
}

// trieprtone -- print single word
void
trieprtone(trie_t *cur)
{
    char *ptr;
    int chr;

    ptr = &trieprt_buf[TRIEPRT_MAX];
    *--ptr = 0;

    // NOTE: the root trie is a dummy and has the only negative value
    for (trie_t *par = cur;  par != NULL;  par = par->trie_par) {
        chr = par->trie_let;
        if (chr < 0)
            break;
        *--ptr = chr + 'A';
    }

    printf("trieprtont: '%s'\n",ptr);
}

// trieprtall -- print all trie elements
void
trieprtall(trie_t *par)
{
    trie_t *cld;

    for (int idx = 0;  idx < LETTERS;  ++idx) {
        cld = par->trie_cld[idx];
        if (cld == NULL)
            continue;

        if (cld->trie_eow)
            trieprtone(cld);

        trieprtall(cld);
    }
}

int
main(int argc,char **argv)
{
    FILE *fi;
    char *file;
    char *bp;
    char *cp;
    char delims[256];
    char buf[10000];

    --argc;
    ++argv;

    // NOTE: this source file makes a good test input
    if (argc > 0)
        file = argv[0];
    else
        file = "wordlist.txt";

    fi = fopen(file,"r");
    if (fi == NULL) {
        fprintf(stderr,"unable to open '%s' -- %s\n",file,strerror(errno));
        exit(1);
    }

    root = trienew(-1);

    cp = delims;
    for (int chr = 1;  chr < 0x7F;  ++chr) {
        if (isalpha(chr))
            continue;
        *cp++ = chr;
    }
    *cp = 0;

    while (1) {
        cp = fgets(buf,sizeof(buf),fi);
        if (cp == NULL)
            break;

        bp = buf;
        while (1) {
            cp = strtok(bp,delims);
            if (cp == NULL)
                break;

            bp = NULL;

            trieword(cp);
        }
    }

    fclose(fi);

    trieprtall(root);

    return 0;
}

推荐阅读