【发布时间】:2016-09-08 04:29:35
【问题描述】:
所以我的程序中有一小部分正在进行基本转换。在这种情况下,从字节缓冲区(基数 256)到基数 58。
我正在尝试将这部分翻译成 C,这样当我需要编写它的其他实现时,我可以重复使用相同的代码。
来自原始 C++:
static unsigned int divide_58(string& x) {
const size_t length = x.length();
size_t pos = 0;
char *quotient = new char[length];
for (size_t i = 0; i < length; ++i) {
const size_t j = i + 1 + x.length() - length;
if (x.length() < j)
break;
const unsigned int value = base2dec(x.c_str(), j); //defined elsewhere; consistent in both
quotient[pos] = (unsigned char)(value / 58);
if (pos != 0 || quotient[pos] != ascii[0])
pos++;
size_t len = 4;
char *temp_str = dec2base(value % 58, len); //defined elsewhere; consistent in both
x.replace(0, j, temp_str, len); //Replace the contents at 0 thru j with the whole contents of temp_str, moving things appropriately
free(temp_str);
}
// calculate remainder
const unsigned int remainder = base2dec(x.c_str(), x.length()); //defined elsewhere; consistent in both
// remove leading "zeros" from quotient and store in 'x'
x.assign(quotient, quotient + pos);
return remainder;
}
我把它翻译成下面的 C:
static unsigned int divide_58(char *x, size_t &length) {
const size_t const_length = length;
size_t pos = 0;
char *quotient = (char*) malloc(sizeof(char) * const_length);
for (size_t i = 0; i < const_length; ++i) {
const size_t j = i + 1 + length - const_length;
if (length < j)
break;
const unsigned int value = base2dec(x, j); //defined elsewhere; consistent in both
quotient[pos] = (unsigned char)(value / 58);
if (pos != 0 || quotient[pos] != ascii[0])
pos++;
size_t len = 4;
char *temp_str = dec2base(value % 58, len); //defined elsewhere; consistent in both
memcpy(x, temp_str, len);
free(temp_str);
memmove(x + len, x + j, length - j);
length -= j;
length += len;
}
// calculate remainder
const unsigned int remainder = base2dec(x, length); //defined elsewhere; consistent in both
// remove leading "zeros" from quotient and store in 'x'
memcpy(x, quotient, pos);
free(quotient);
length = pos;
return remainder;
}
这在几乎所有情况下都有效,但在我的 Linux 测试环境(并且没有我的本地机器)上它会产生错误的答案,尽管同意输入是正确的。
失败示例:https://app.shippable.com/runs/57cf7ae56f908e0e00c5e451/1/console (build_ci -> make cpytest cov=true)
工作示例:https://travis-ci.org/gappleto97/p2p-project/jobs/158036360#L392
我知道标准是提供问题的最短示例,但据我所知是最短的示例。大家能帮帮我吗?
对于 MCVE 人员,您可以通过我的 git repo 自己验证这一点。
git clone https://github.com/gappleto97/p2p-project
cd p2p-project
git checkout develop
make cpytest
git checkout c_issue
rm -r build
make cpytest
第一次调用 make 将有失败的测试。第二个不会。第二个是使用这里提供的 C++ 代码,第一个是使用这里提供的 C 代码。为了便于测试,它被提升为 Python,但我已将其范围缩小到这个函数。不过这可能没用,因为我只能在 Shippable 上复制错误。
【问题讨论】:
-
没有 MCVE。
dec2base和base2dec不在那里。代码不是C,需要C++编译器编译。memcpy在缓冲区内复制。使用memmove。 -
^ 在没有 MCVE 的情况下非常正确
-
您确实需要改进有关没有 MCVE 的问题。其中包括问题的详细信息,例如您在调试时发现的问题
-
char *quotient = new char[const_length];- 那是 C 代码吗?进一步 - 这不是内存泄漏吗? -
您真的执行一次 malloc 和 free
length次,而不是将缓冲区传递给 base2dec ????此外,我要提醒您,C 不是 C++ 的子集,它是一门独立的语言,自 30 多年前诞生 C++ 以来,它一直沿着自己的轨道发展。这会让人们失望。老实说,你写的不是 C,而是糟糕的 C++。如果代码质量对您很重要,我鼓励您使用 codereview.stackexchange.com 获得适当的转换帮助。