当我在 Docker 中运行用 G ++ 编译的程序时的不同行为
Different behavior when I running a program compiled with G ++ in Docker
如果可执行文件在 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 %snnn", cAux2);
sprintf(cAux2, "%s%c", cAux2, (nRest+65));
printf("AFTER SPRINTF %snnn", 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 构建 -t 快速编译 .
$docker运行快速编译
BEFORE SPRINTF 003395
AFTER SPRINTF P
如果我删除 -O 并使用以下命令重新编译:
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
,因为你的格式说明符声明它应该是。 这也是未定义的行为。 您需要将其转换为字符以修复它,例如
sprintf(cAux2, "%s%c", cOrd, char(nRest+65));
相关文章:
- 这是使用回溯的 nqueen 问题,但我使用了动态 2d 数组,我的程序编译良好,但不返回任何输出
- C ++程序编译错误,找不到/访问文件
- C++程序编译没有问题,但无法运行
- Mongdb C++ 驱动程序编译错误 for document{}.
- 添加类型名会导致程序编译失败
- 将 C 程序更改为 C++ 程序 - 编译错误
- 程序编译,但当分解为函数时实际上不会移动电机
- 如何链接 glib-2.0 库进行 c/c++ 程序编译
- 为什么 gcc 和 clang 为我的程序编译为不同的"const"结果?
- 复数程序编译时的计算方法错误
- qt 命令行应用程序编译
- 程序编译和运行,但一段时间后,它停止使用Typedef关键字在CPP上工作
- QML应用程序编译一个 *form.ui.qml文件,但忽略了关联的.qml文件
- 为什么该程序编译但不显示任何输出
- 分割故障程序编译为共享库,但不静态
- 程序编译,但我认为开关被忽略
- 程序编译后崩溃
- 什么是程序编译中的PIC级别
- 尽管使用不存在的成员,但程序编译
- C++程序编译在 Ubuntu 中失败,但在 MacOSX 中工作