【问题标题】:For loop not terminating in cFor循环未在c中终止
【发布时间】:2011-11-02 03:31:29
【问题描述】:

我正在编写一些代码,但遇到一个奇怪的错误:当条件语句变为 false 时,我的 for 循环似乎没有退出。代码如下:

static void wstrcpy_from_Py_UNICODE(Py_UNICODE *inBuf, Py_ssize_t strLength, wchar_t **outBuf)
{
    if (strLength == 0) *outBuf = NULL;
    else
    {
        Py_ssize_t i;
        wprintf(L"String Length: %d\n", strLength);
        *outBuf = (wchar_t *)malloc (sizeof (wchar_t) * (strLength +1));
        for (i=0; i < strLength; i++)
        {
            wprintf("i:%d, strLength:%d\n", i, strLength);
            (*outBuf)[i] = (wchar_t)(inBuf[i]);
            wprintf(L"i < strLength: %d\n\n", i < strLength);
        }
    /* Make sure new string is zero terminated */
    (*outBuf)[i] = L'\0';
    }
}

当使用示例输入运行此代码时,(Py_UNICODE * 缓冲区指向使用 u"example" 生成的内部 unicode python 对象)我得到以下输出:

String Length: 7
i:0, strLength: 7
i < strLength: 1

i:1, strLength: 7
i < strLength: 1

i:2, strLength: 7
i < strLength: 1

i:3, strLength: 7
i < strLength: 1

i:4, strLength: 7
i < strLength: 1

i:5, strLength: 7
i < strLength: 1

i:6, strLength: 7
i < strLength: 1

i:7, strLength: 7
i < strLength: 1

i:8, strLength: 7
i < strLength: 1

...

在运行代码的python解释器(我正在为python包装一个c模块)崩溃之前,循环不会退出。

已将 printf 用于调试。

我在 Mac OSX 10.6 上编译这个,这里是我用来编译的命令:

gcc -c source.c -I/usr/include/python2.6 -I/usr/lib/python2.6
ld -bundle -flat_namespace -undefined suppress -o out.so source.o -F./ -framework some_framework -macosx_version_min 10.6 -rpath ./

如您所见,我正在为其制作 python 包装器的框架中进行链接。这不是问题,因为我可以很好地调用使用链接框架的函数,只是当我调用使用上面显示的辅助函数的函数时,我会遇到问题。

我在这里是不是很愚蠢并且做了一些非常基本的错误,还是编译器有问题?任何帮助将不胜感激!

【问题讨论】:

  • 真的很奇怪的错误!我想我会看一下汇编代码,看看它对循环做了什么。我认为编译器搞砸了一些东西。也许 Py_ssize_t 的类型定义有些混乱?

标签: c for-loop


【解决方案1】:

您可以尝试使用 int i 和 int strLength 吗?

我不知道Py_ssize_t 类型,但printf%d 的隐式转换可能会隐藏问题

【讨论】:

  • 成功了! (好吧,我将 strLength 转换为新的 int 并将 i 声明为 int)
  • @user980127:小心那个“修复”——这表明打电话给wstrcpy_from_Py_UNICODE()的人错误地传递了strLength(或者你应该复制一个巨大的字符串) .您的问题的根本原因可能是“上游” - 您应该注意这一点,而不是掩盖wstrcpy_from_Py_UNICODE() 内部的问题。
【解决方案2】:

Py_ssize_t 是什么?

printf("sizeof (int) is %d\n", (int)sizeof (int));
printf("sizeof (Py_ssize_t) is %d\n", (int)sizeof (Py_ssize_t));

除了使用char* (一次)调用wprintf 之外,您还使用"%d" 说明符来处理Py_ssize_t 类型的值

【讨论】:

    【解决方案3】:

    我认为这主要与数字精度有关。如果 Py_ssize_t 是 64 位类型,它可能是以下形式:0xffffffff00000008(可能是因为先前的计算值涉及不正确的精度数字,或者混合有符号和无符号计算)。当考虑为int(32 位)时,其结果为 8,但当考虑为 64 位值时,它产生一个非常小的负数(有符号)或一个非常大的正数(无符号)。尝试更改 wprintf 表达式以写入长小数 (%ld) 并查看打印的内容,或使用 gdb 调试代码以查看实际大小的数字。

    【讨论】:

    • 当我将 wprintf 更改为使用 %ld 时,我得到的数字是 4294967303,对应于 0x100000007。好收获!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-18
    • 2021-09-18
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多