(在继续之前,没有释放和编写代码中从未使用过的变量,
用于测试工具)
我写了像这样的代码和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
当我把make all时,会显示以下消息:
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
我应该修理什么?
答案 0 :(得分: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
或者在这种特殊情况下,你可能有理由用“旧skool”的方式做一个宏:
// unread_two.h
#define SIZEOF_INT sizeof(int)
答案 1 :(得分:2)
你实际上有两个错误,你报告的错误和另一个更狡猾的错误。
您遇到错误的问题是,在包含头文件的所有源文件中定义了常量SIZEOF_INT
。包含保护仅防止多个包含在同一源文件(或技术上的翻译单元)中说话),但不是你在多个来源中包含相同的文件。这意味着编译器将在SIZEOF_INT
和unread_twomain.o
中创建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;
}