c++ - 当我在 Docker 中运行使用 G ++ 编译的程序时的不同行为
问题描述
如果可执行文件在 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 快速编译。
$docker 运行快速编译
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)
为您提供了 a int
,而不是char
格式说明符声明的 a 。这也是未定义的行为。您需要将其转换为 char 来修复它
sprintf(cAux2, "%s%c", cOrd, char(nRest+65));
推荐阅读
- javascript - 如何使可拖动的可排序列表在拖动时显示其他内容?
- pandas - 熊猫数据框到 coo 矩阵和 lil matix
- html - 基于网络的 Gmail 显示连续的空白但不打印
- java - Eclipse Formatter - 忽略 if 条件中的内容
- html - 按钮与文本区域不在同一行
- scala - 如何在数据块中展开数据框模式
- ios - 未从自定义 URL 调用 iOS AppDelegate
- flutter - Flutter - 如何使用 BloC 实现下拉列表?
- javascript - 在Javascript中单击运算符(+ - ..)后如何存储每个值
- processing - 迫使球体旋转