1

(在继续之前,
没有释放代码和编写从未在代码中使用的变量,
旨在测试工具)

我编写了这样的代码和这样的 Makefile:

unread_two.h

#ifndef __UNREAD_TWO_H
#define __UNREAD_TWO_H

const int SIZEOF_INT = sizeof(int);
int addTwo();

unread_twomain.c

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

int main(int argc, char *argv[])
{
    int *x;

    x = (int *)malloc(SIZEOF_INT);
    x = addTwo();
    free(x);

    return 0;
}

unread_two.c

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

int addTwo()
{
    int *y, *z, sum;
    y = (int *)malloc(SIZEOF_INT);
    z = (int *)malloc(SIZEOF_INT);

    *y = 3;
    sum = *y + *y;
    return sum;
}

生成文件

CC=gcc
CCFLAGS=-g

%.o: %.c
    $(CC) -c $< $(CCFLAGS)

all: unread_two
clobber: clean
    rm -f *~ \#`\# core

clean:
    rm -f unread_two *.o

unread_two: unread_twomain.o unread_two.o

unread_twomain.o: unread_two.h

unread_two.o: unread_two.h

当我全部制作时,会出现以下消息:

unread_twomain.o:(.rodata+0x0): multiple definition of `SIZEOF_INT'
unread_two.o:(.rodata+0x0): first defined here
collect2: error: ld returned 1 exit status

我应该解决哪些问题?

4

2 回答 2

4

您不应该在标头中进行定义 SIZEOF_INT,否则当您将此标头包含在多个编译单元中时,您将获得多个定义,如您所见。而是在头文件中声明它并在源文件中定义它:

// unread_two.h

extern const int SIZEOF_INT;         // *declare* SIZEOF_INT


// unread_two.c

const int SIZEOF_INT = sizeof(int);  // *define* SIZEOF_INT


或者,在这种特殊情况下,您可能有理由使用“old skool”方式使用宏:

// unread_two.h

#define SIZEOF_INT sizeof(int)
于 2013-10-07T10:04:19.180 回答
2

您实际上有两个错误,一个是您报告的错误,另一个是更狡猾的错误。

您遇到错误的问题是该常量SIZEOF_INT是在您包含头文件的所有源文件中定义的。包含防护仅防止在同一源文件(或从技术上讲是翻译单元)中多次包含,但不包括在内多个来源中的同一个文件。这意味着编译器将SIZEOF_INTunread_twomain.oand中创建一个定义unread_two.o,然后链接器会抱怨。

对此的解决方案是只在头文件中声明常量,然后在单个源文件中定义它。


另一个问题是,main你创建x一个指针,并为它分配内存(顺便说一下,你不应该对 的返回进行类型转换malloc),然后将结果赋值addTwo给这个指针。但addTwo不返回指针,它返回一个直接值,所以你让指针指向我猜想的不是你打算做x的地址。当您尝试释放 指向的内存时,6这将导致未定义的行为x,很可能导致崩溃。

在您的程序中,您根本不必使用指针。只需使用普通的非指针变量:

int addTwo()
{
    int y = 3;
    int sum = y + y;

    return sum;
}

int main(int argc, char *argv[])
{
    int x = addTwo();

    return 0;
}
于 2013-10-07T10:08:31.583 回答