如果可执行文件在docker内部或主机上运行,则其行为会有所不同。但这只有在我们改变G ++的优化级别时才会发生。
编译器:g ++(Ubuntu 7.3.0-27ubuntu1~18.04)7.3.0
我正在尝试执行以下代码:
#include <cstdio>
#include <cstring>
int main()
{
int nOrd =3395;
char cOrd[] = "003395";
char cAux2[256];
strcpy(cAux2, cOrd);
int nRest = nOrd % 26;
printf("BEFORE SPRINTF %s\n\n\n", cAux2);
sprintf(cAux2, "%s%c", cAux2, (nRest+65));
printf("AFTER SPRINTF %s\n\n\n", cAux2);
return 0;
}
如果我编译:
g++ -o FastCompile FastCompile.c -DNDEBUG -Os
我在主持人中跑步。输出如预期:
BEFORE SPRINTF 003395
AFTER SPRINTF 003395P
如果我用这个可执行文件创建一个图像并在docker中运行,我有:
Docker版本18.09.4,构建d14af54266
Dockerfile:
FROM debian
RUN apt-get update && apt-get install -y \
libssl-dev
COPY fast/ /usr/local/
ENTRYPOINT ["usr/local/FastCompile"]
$ docker build -t fastcompile。
$ docker run fastcompile
BEFORE SPRINTF 003395
AFTER SPRINTF P
如果我删除-Os并重新编译:
g++ -o FastCompile FastCompile.c -DNDEBUG
Docker中的行为是正确的。
那么,它是Docker问题吗?或者是预期的行为?
您的代码具有未定义的行为。
sprintf(cAux2, "%s%c", cAux2, (nRest+65));
读取和写入同一对象。要修复它,您可以在调用中使用cOrd
,这样您就不会从缓冲区中读取数据。那看起来像
sprintf(cAux2, "%s%c", cOrd, (nRest+65));
还要注意(nRest+65)
给你一个int
,而不是char
,因为你应该格式化说明符状态。这也是未定义的行为。您需要将其强制转换为char来修复它
sprintf(cAux2, "%s%c", cOrd, char(nRest+65));