gpt4 book ai didi

c - 对 memdup 的 undefined reference

转载 作者:行者123 更新时间:2023-11-30 17:54:54 25 4
gpt4 key购买 nike

我的目录中有 5 个文件。我正在尝试使用 gcc -o mini2.c -pthread -utils 编译我的程序,但出现以下错误:

/tmp/cc2W2ocr.o: In function `fifo_put':
mini2.c:(.text+0x59): undefined reference to `memdup'
collect2: ld returned 1 exit status

有什么想法可以使 memdup 函数对编译器可见吗?我在目录中的文件是:

  • mini2.c

            // Mini Assignment 1
    // Author: Georges Krinker
    // Student #: 260369844
    // Course: ECSE 427 (OS)


    #include <stdio.h>
    #include <stdlib.h>

    extern char etext, edata,end;
    int not_init;
    int init =10;
    int dat =20;

    int main(void){

    char *stack = (char*)alloca(10000);
    int pid;
    char *dynamic_var = (char*)malloc(4000);
    int c =0;
    FILE *file;
    char l[8000];
    int len=8000;
    char s [1200];

    // To find where the stack is we use the start of the last declared local variable s.
    // This is because of the LIFO nature of the stack
    // For a more accurate look at proc/pid/smaps and see the stack range (Readme.html)


    printf("The stack starts approx. at %p\n", &s[1200]);

    printf("The stack ends at %p\n\n", stack-10000);

    // The most reliable way to obtain the Memory mapping segment is to read
    // the proc/pid/maps file. (see Readme.html)

    printf("The entire memory mapping segment spans:\n");

    sprintf(s, "/proc/%d/maps", pid=getpid());

    file = fopen(s, "r");
    if (file) {
    //skip first 4 lines of the maps file
    fgets(l, len, file);
    fgets(l, len, file);
    fgets(l, len, file);
    fgets(l, len, file);
    fgets(l, len, file);
    while (c <= 9) {
    fgets(l, len, file);
    fputs ( l, stdout ); /*print the memeory mapping segments */
    c++;
    }
    }
    fclose(file);

    // Use the start of the dyn. allocated variable for the start of the heap.
    // There is a 8 byte offset that I noticed when comparing my obtained
    // address with the process's smap file which is why I subtract 8. (See Readme.html)

    printf("\n\nThe Heap segment starts at %p\n", dynamic_var-8);

    // Add the size of that variable to the start address to get the end of the heap

    printf("The heap ends at %p\n\n", dynamic_var+100-8);

    // Use the symbol edata to find the start of BSS

    printf("The BSS segment starts after %10p \n\n", &edata);

    // The end of text and start of data is the location of
    // the single initialized global variable init.

    printf("The data segment starts at %10p\n\n", &init);

    //Use the address of main for the start of text.
    // For a more accurate number, do objdump -x <filename> and
    // look for .text in the <filename> section (see Readme.html)

    printf("The start of text is approximately at %p\n\n", main);

    printf("For more info, check the comments of this source code and the Readme.html\n\n");


    return 0;

    }
  • utils.c

        /* source: utils.c */
    /* Copyright Gerhard Rieger 2001-2009 */
    /* Published under the GNU General Public License V.2, see file COPYING */

    /* useful additions to C library */

    #include "config.h"

    #include "sysincludes.h"

    #include "compat.h" /* socklen_t */
    #include "mytypes.h"
    #include "sycls.h"
    #include "utils.h"


    #if !HAVE_MEMRCHR
    /* GNU extension, available since glibc 2.1.91 */
    void *memrchr(const void *s, int c, size_t n) {
    const unsigned char *t = ((unsigned char *)s)+n;
    while (--t >= (unsigned char *)s) {
    if (*t == c) break;
    }
    if (t < (unsigned char *)s)
    return NULL;
    return (void *)t;
    }
    #endif /* !HAVE_MEMRCHR */

    void *memdup(const void *src, size_t n) {
    void *dest;

    if ((dest = Malloc(n)) == NULL) {
    return NULL;
    }

    memcpy(dest, src, n);
    return dest;
    }

    /* search the keyword-table for a match of the leading part of name. */
    /* returns the pointer to the matching field of the keyword or NULL if no
    keyword was found. */
    const struct wordent *keyw(const struct wordent *keywds, const char *name, unsigned int nkeys) {
    unsigned int lower, upper, mid;
    int r;

    lower = 0;
    upper = nkeys;

    while (upper - lower > 1)
    {
    mid = (upper + lower) >> 1;
    if (!(r = strcasecmp(keywds[mid].name, name)))
    {
    return &keywds[mid];
    }
    if (r < 0)
    lower = mid;
    else
    upper = mid;
    }
    if (nkeys > 0 && !(strcasecmp(keywds[lower].name, name)))
    {
    return &keywds[lower];
    }
    return NULL;
    }

    /* Linux: setenv(), AIX: putenv() */
    #if !HAVE_SETENV
    int setenv(const char *name, const char *value, int overwrite) {
    int result;
    char *env;
    if (!overwrite) {
    if (getenv(name)) return 0; /* already exists */
    }
    if ((env = Malloc(strlen(name)+strlen(value)+2)) == NULL) {
    return -1;
    }
    sprintf(env, "%s=%s", name, value);
    if ((result = putenv(env)) != 0) { /* AIX docu says "... nonzero ..." */
    free(env);
    result = -1;
    }
    /* linux "man putenv" says: ...this string becomes part of the environment*/
    return result;
    }
    #endif /* !HAVE_SETENV */



    /* sanitize an "untrusted" character. output buffer must provide at least 5
    characters space.
    Does not append null. returns length out output (currently: max 4) */
    static size_t sanitize_char(char c, char *o, int style) {
    int hn; /* high nibble */
    int ln; /* low nibble */
    int n; /* written chars */
    if (isprint(c)) {
    *o = c;
    return 1;
    }
    *o++ = '\\';
    n = 2;
    switch (c) {
    case '\0': *o++ = '0'; break;
    case '\a': *o++ = 'a'; break;
    case '\b': *o++ = 'b'; break;
    case '\t': *o++ = 't'; break;
    case '\n': *o++ = 'n'; break;
    case '\v': *o++ = 'v'; break;
    case '\f': *o++ = 'f'; break;
    case '\r': *o++ = 'r'; break;
    case '\'': *o++ = '\''; break;
    case '\"': *o++ = '"'; break;
    case '\\': *o++ = '\\'; break;
    default:
    *o++ = 'x';
    hn = (c>>4)&0x0f;
    ln = c&0x0f;
    *o++ = (hn>=10 ? (('A'-1)+(hn-10)) : ('0'+hn));
    *o++ = (ln>=10 ? (('A'-1)+(ln-10)) : ('0'+ln));
    n = 4;
    }
    return n;
    }

    /* sanitize "untrusted" text, replacing special control characters with the C
    string version ("\x"), and replacing unprintable chars with ".".
    text can grow to four times of input, so keep output buffer long enough!
    returns a pointer to the first untouched byte of the output buffer.
    */
    char *sanitize_string(const char *data, /* input data */
    size_t bytes, /* length of input data, >=0 */
    char *coded, /* output buffer, must be long enough */
    int style
    ) {
    int c;

    while (bytes > 0) {
    c = *(unsigned char *)data++;
    coded += sanitize_char(c, coded, style);
    --bytes;
    }
    return coded;
    }

    /* copies a substring out of a given buff
    returns scratch, \0 terminated; scratch must provide len+1 bytes
    */
    char *xiosubstr(char *scratch, const char *str, size_t from, size_t len) {
    char *scratch0 = scratch;
    str += from;
    while (len--) {
    *scratch++ = *str++;
    }
    *scratch = '\0';
    return scratch0;
    }
  • utils.h

                            /* source: utils.h */
    /* Copyright Gerhard Rieger 2001-2008 */
    /* Published under the GNU General Public License V.2, see file COPYING */

    #ifndef __utils_h_included
    #define __utils_h_included 1

    /* a generic name table entry */
    struct wordent {
    const char *name;
    void *desc;
    } ;

    #if !HAVE_MEMRCHR
    extern void *memrchr(const void *s, int c, size_t n);
    #endif
    extern void *memdup(const void *src, size_t n);
    #if !HAVE_SETENV
    extern int setenv(const char *name, const char *value, int overwrite);
    #endif /* !HAVE_SETENV */

    extern const struct wordent *keyw(const struct wordent *keywds, const char *name, unsigned int nkeys);


    #define XIOSAN_ZERO_MASK 0x000f
    #define XIOSAN_ZERO_DEFAULT 0x0000
    #define XIOSAN_ZERO_DOT 0x0001
    #define XIOSAN_ZERO_BACKSLASH_OCT_3 0x0002
    #define XIOSAN_ZERO_BACKSLASH_OCT_4 0x0003
    #define XIOSAN_ZERO_BACKSLASHX_HEX_UP 0x0004
    #define XIOSAN_ZERO_BACKSLASHX_HEX_LOW 0x0005
    #define XIOSAN_ZERO_PERCENT_HEX_UP 0x0006
    #define XIOSAN_ZERO_PERCENT_HEX_LOW 0x0007
    #define XIOSAN_CONTROL_MASK 0x00f0
    #define XIOSAN_CONTROL_DEFAULT 0x0000
    #define XIOSAN_CONTROL_DOT 0x0010
    #define XIOSAN_CONTROL_BACKSLASH_OCT_3 0x0020
    #define XIOSAN_CONTROL_BACKSLASH_OCT_4 0x0030
    #define XIOSAN_CONTROL_BACKSLASHX_HEX_UP 0x0040
    #define XIOSAN_CONTROL_BACKSLASHX_HEX_LOW 0x0050
    #define XIOSAN_CONTROL_PERCENT_HEX_UP 0x0060
    #define XIOSAN_CONTROL_PERCENT_HEX_LOW 0x0070
    #define XIOSAN_UNPRINT_MASK 0x0f00
    #define XIOSAN_UNPRINT_DEFAULT 0x0000
    #define XIOSAN_UNPRINT_DOT 0x0100
    #define XIOSAN_UNPRINT_BACKSLASH_OCT_3 0x0200
    #define XIOSAN_UNPRINT_BACKSLASH_OCT_4 0x0300
    #define XIOSAN_UNPRINT_BACKSLASHX_HEX_UP 0x0400
    #define XIOSAN_UNPRINT_BACKSLASHX_HEX_LOW 0x0500
    #define XIOSAN_UNPRINT_PERCENT_HEX_UP 0x0600
    #define XIOSAN_UNPRINT_PERCENT_HEX_LOW 0x0700
    #define XIOSAN_DEFAULT_MASK 0xf000
    #define XIOSAN_DEFAULT_BACKSLASH_DOT 0x1000
    #define XIOSAN_DEFAULT_BACKSLASH_OCT_3 0x2000
    #define XIOSAN_DEFAULT_BACKSLASH_OCT_4 0x3000
    #define XIOSAN_DEFAULT_BACKSLASHX_HEX_UP 0x4000
    #define XIOSAN_DEFAULT_BACKSLASHX_HEX_LOW 0x5000
    #define XIOSAN_DEFAULT_PERCENT_HEX_UP 0x6000
    #define XIOSAN_DEFAULT_PERCENT_HEX_LOW 0x7000

    extern
    char *sanitize_string(const char *data, /* input data */
    size_t bytes, /* length of input data, >=0 */
    char *coded, /* output buffer, must be long enough */
    int style);
    extern
    char *xiosubstr(char *scratch, const char *str, size_t from, size_t len);

    #endif /* !defined(__utils_h_included) */
  • fifo.c

                            /*
    * fifo.c
    *
    * A simple FIFO implementation.
    *
    * Copyright (C) 2010, Marek Polacek <xpolac06@stud.fit.vutbr.cz>
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "fifo.h"
    #include "utils.h"

    void fifo_put(fifo_t *fifo, char *data, size_t size)
    {
    struct item *i;
    i = malloc(sizeof(*i));
    if (!i) {
    perror("malloc");
    exit(EXIT_FAILURE);
    }

    if (size) {
    data = memdup(data, size);
    if (!data) {
    fputs("fatal: out of memory\n", stderr);
    free(i);
    exit(EXIT_FAILURE);
    }
    }

    i->next = NULL;
    i->buf = data;

    if (!fifo->tail) {
    fifo->head = i;
    fifo->tail = i;
    } else {
    fifo->tail->next = i;
    fifo->tail = i;
    }
    }

    char *fifo_get(fifo_t *fifo)
    {
    struct item *i;
    char *data;

    assert(fifo != NULL);
    if (fifo_empty(fifo))
    return NULL;

    i = fifo->head;
    data = i->buf;

    fifo->head = i->next;
    if (!fifo->head)
    fifo->tail = NULL;
    free(i);

    return data;
    }

    void fifo_free(fifo_t *fifo)
    {
    assert(fifo != NULL);
    while (fifo->head)
    (void) fifo_get(fifo);
    free(fifo);
    }

    fifo_t *fifo_init(void)
    {
    fifo_t *fifo;
    fifo = malloc(sizeof(*fifo));
    if (!fifo) {
    perror("malloc");
    exit(EXIT_FAILURE);
    }

    fifo->head = NULL;
    fifo->tail = NULL;
    return fifo;
    }
  • fifo.h

                            /*
    * fifo.h
    *
    * A simple FIFO implementation.
    *
    * Copyright (C) 2010, Marek Polacek <xpolac06@stud.fit.vutbr.cz>
    */

    #ifndef FIFO_H
    #define FIFO_H

    #include <assert.h>

    struct item {
    char *buf;
    struct item *next;
    };

    struct fifo {
    struct item *head;
    struct item *tail;
    };

    typedef struct fifo fifo_t;

    extern fifo_t *fifo_init(void);
    extern void fifo_free(fifo_t *);
    extern char *fifo_get(fifo_t *);
    extern void fifo_put(fifo_t *, char *, size_t);

    static inline int fifo_empty(fifo_t *fifo)
    {
    return (fifo->head == NULL);
    }

    static inline char *fifo_peek(fifo_t *fifo)
    {
    assert(fifo != NULL);
    if (!fifo_empty(fifo))
    return fifo->head->buf;
    else
    return NULL;
    }

    #endif /* FIFO_H */

最佳答案

编译器的当前调用根本没有意义(将输出写入 C 文件?什么是 -util?)。 Read something up on C compilation 。您需要将所有目标文件链接在一起,例如

gcc -o myprog myprog.c util.c

就足够了。

关于c - 对 memdup 的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14675394/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com