c - 海合会 "multiple definition of "错误

标签 c gcc

所以我有这三个文件

主.c

#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include "support.h"

int main( void ) {
    int* num1 = malloc(100);
    printf("num1: %p", &num1);
}

支持.c

#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include "support.h"

void *malloc(size_t size) {
    struct block_meta *block;
    if (size <= 0) {
        return NULL;
    }
    if (!global_base) { // First call.
    block = request_space(NULL, size);
        if (!block) {
            return NULL;
        }
        global_base = block;
    } else {
        struct block_meta *last = global_base;
        block = find_free_block(&last, size);
        if (!block) { // Failed to find free block.
            block = request_space(last, size);
            if (!block) {
                return NULL;
            }
        } else { // Found free block
            block->free = 0;
            block->magic = 0x77777777;
        }
    }
    return(block+1);
}


void free(void *ptr) {
    if (!ptr) {
        return;
    }
    struct block_meta* block_ptr = get_block_ptr(ptr);
    assert(block_ptr->free == 0);
    assert(block_ptr->magic == 0x77777777 || block_ptr->magic == 0x12345678);
    block_ptr->free = 1;
    block_ptr->magic = 0x55555555;
}

void *realloc(void *ptr, size_t size) {
    if (!ptr) {
        // NULL ptr. realloc should act like malloc.
        return malloc(size);
    }
    struct block_meta* block_ptr = get_block_ptr(ptr);
    if (block_ptr->size >= size) {
        // We have enough space. Could free some once we implement split.
        return ptr;
    }
    // Need to really realloc. Malloc new space and free old space.
    // Then copy old data to new space.
    void *new_ptr;
    new_ptr = malloc(size);
    if (!new_ptr) {
        return NULL; // TODO: set errno on failure.
    }
    memcpy(new_ptr, ptr, block_ptr->size);
    free(ptr);
    return new_ptr;
}

void *calloc(size_t nelem, size_t elsize) {
    size_t size = nelem * elsize; // TODO: check for overflow.
    void *ptr = malloc(size);
    memset(ptr, 0, size);
    return ptr;
}

支持.h

#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);


struct block_meta {
    size_t size;
    struct block_meta *next;
    int free;
    int magic; // For debugging only. TODO: remove this in non-debug mode.
};

#define META_SIZE sizeof(struct block_meta)

void *global_base = NULL;

struct block_meta *find_free_block(struct block_meta **last, size_t size) {
    struct block_meta *current = global_base;
    while (current && !(current->free && current->size >= size)) {
        *last = current;
        current = current->next;
    }
    return current;
}

struct block_meta *request_space(struct block_meta* last, size_t size) {
    struct block_meta *block;
    block = sbrk(0);
    void *request = sbrk(size + META_SIZE);
    assert((void*)block == request); // Not thread safe.
    if (request == (void*) -1) {
        return NULL; // sbrk failed.
    }
    if (last) { // NULL on first request.
        last->next = block;
    }
    block->size = size;
    block->next = NULL;
    block->free = 0;
    block->magic = 0x12345678;
    return block;
}

struct block_meta *get_block_ptr(void *ptr) {
    return (struct block_meta*)ptr - 1;
}

但是,当我尝试使用

进行编译时
gcc -o asgn2 main.c support.c

我得到了错误

/tmp/ccscmcbS.o:(.bss+0x0): multiple definition of `global_base'
/tmp/ccyjhjQC.o:(.bss+0x0): first defined here
/tmp/ccscmcbS.o: In function `find_free_block':
support.c:(.text+0x0): multiple definition of `find_free_block'
/tmp/ccyjhjQC.o:main.c:(.text+0x0): first defined here
/tmp/ccscmcbS.o: In function `request_space':
support.c:(.text+0x55): multiple definition of `request_space'
/tmp/ccyjhjQC.o:main.c:(.text+0x55): first defined here
/tmp/ccscmcbS.o: In function `get_block_ptr':
support.c:(.text+0xfe): multiple definition of `get_block_ptr'
/tmp/ccyjhjQC.o:main.c:(.text+0xfe): first defined here
collect2: error: ld returned 1 exit status

我不相信我不止一次地声明了这些方法,而且它的格式与我通常给出的格式大不相同。不太清楚这是什么意思。

最佳答案

问题是您的头文件中有函数和全局变量定义(相对于声明)。因此,这些函数在编译时被拉入 main.c 和 support.c。然后在链接阶段,链接器会看到多个定义。

即使你有 include guards,在这种情况下也无济于事,因为它只能防御单个编译单元中的多个定义,而不是跨多个单元。

从头文件中取出这些函数的定义,用声明替换它们,并将它们放在 support.c 或单独的 .c 文件中。

关于c - 海合会 "multiple definition of "错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36209788/

相关文章:

c - 重定位分配器发生了什么?

c - 清晰可视化 C 程序的内存布局的工具

c++ - 在 Mingw 上编译的 C/C++ 代码会保证与 GCC 完全兼容(在 linux 和 Mac 上)

c++ - Mingw+MSYS 中 libevent 的静态编译错误

使用 Python.h undefined symbol 的 C++ 编译

gcc - LLVM 中的内联 NOP 未优化

c - 如何在C中定义 "constant"结构

c++ - Pi 计算器程序每次运行时都会给出不同的输出

c - 结构 - 访问不带 .和 ->

c - .in'ig.status : error: cannot find input file: `Makefile