【问题标题】:C99 command-line does not print anything in this C programming case在此 C 编程案例中,C99 命令行不打印任何内容
【发布时间】:2011-12-14 17:43:50
【问题描述】:

我今天遇到了一个奇怪的 C 问题。快速看一下这个简化的代码 sn-p:

typedef struct
{
    /* The number of index terms */
    int nTerms;
    /* Information about each index term */
    TERMINFO *terms;
} INDEX;

INDEX *buildIndex(char *termsfile, char *dirs[], int n, OPTIONS opts)
{
    INDEX *ind = NULL;
    ind->nTerms = 5;
    return ind;
}

int main(int argc, char *argv[]) {
    ... // declare and assign values for TERMFILE, DIRS and opts.
    INDEX *ind = buildIndex(TERMFILE, DIRS, sizeof(DIRS), opts); // LINE A 
    printf("Does NOT print %d\n",ind->nTerms); // LINE B
    printf("Does NOT print as well"); // LINE C
    return 0;
}

当我编译这个程序时,没有发生错误,但是当我运行编译后的文件时,它不会向命令行打印任何内容(我在 Windows 机器上使用 PuTTy)。把LINE ALINE B这行去掉就更奇怪了,就可以打印LINE C了。

简而言之,LINE A 之后的任何内容都无法打印出来(或执行?)。

不知道我的代码有没有问题。

【问题讨论】:

  • 你的第二个LINE A 是不是应该是LINE B
  • 抱歉,有人帮我编辑了

标签: c pointers struct c99


【解决方案1】:

在第二行,您正在取消引用 NULL 指针,这会导致未定义的行为:

INDEX *ind = NULL;
ind->nTerms = 5;
return ind;

您需要使ind指向非本地内存,即使用malloc从堆中分配它,或者将其设置为指向具有全局生命周期的变量:

INDEX *ind = malloc(sizeof(INDEX));

if (ind != NULL)
    ind->nTerms = 5;

return ind;

在这种情况下,释放返回的结构(如果它为 NULL,则不取消引用它)的责任委托给调用者。

请注意,如果您将 ind 设置为指向本地声明的变量并返回它,则每当调用者尝试取消引用指针时都会发生 UB,因为在函数终止后会恢复堆栈。

【讨论】:

  • +1 未定义的行为,在这种情况下很可能是崩溃。
  • +1 未定义的行为,但 没有 坚持认为它会崩溃。运行完成但不输出任何内容作为 UB 是完全可以接受的。机器自身坍塌形成裸奇点也是如此。 任何事情都有可能发生!
  • @Blagovest,我做了一些小调整来处理 malloc 错误,希望你不要介意。
【解决方案2】:

它不打印任何东西的原因是因为它正在崩溃:

INDEX *ind = NULL;
ind->nTerms = 5;

您正在取消引用 NULL。 (这是未定义的行为)

当您删除 LINE A 和 LINE B 时,它不会崩溃,因此会打印 LINE C。(您还忘记了 LINE C 中的 \n 来刷新缓冲区。)

您需要做的是通过 malloc 动态分配 ind 并返回。 (并确保稍后释放它)

INDEX *buildIndex(char *termsfile, char *dirs[], int n, OPTIONS opts)
{
    INDEX *ind = malloc(sizeof(INDEX));   //  Allocate

    //  You may wish to check if `ind == NULL` to see if the allocation failed.

    ind->nTerms = 5;
    return ind;
}

int main(int argc, char *argv[]) {
    ... // declare and assign values for TERMFILE, DIRS and opts.
    INDEX *ind = buildIndex(TERMFILE, DIRS, sizeof(DIRS), opts); // LINE A 
    printf("Does NOT print %d\n",ind->nTerms); // LINE B
    printf("Does NOT print as well"); // LINE C

    free(ind);  //  Free

    return 0;
}

【讨论】:

  • 请注意,通常不鼓励在函数中分配对象并在程序的另一部分释放它。您可以在 main 中分配指针,将其作为参数传递给 buildIndex(),然后在 main 中将 free() 传递给它。
【解决方案3】:

您的问题似乎在 buildIndex 中

INDEX *buildIndex(char *termsfile, char *dirs[], int n, OPTIONS opts) 
{
    INDEX *ind = NULL;
    ind->nTerms = 5;
    return ind; 
}

如您所见,您将ind 设置为NULL,然后尝试立即引用。这是未定义的行为,所以接下来可能发生任何事情。

【讨论】:

    【解决方案4】:

    您调用包含这两行的函数buildIndex

    索引 *ind = NULL; ind->nTerms = 5;

    所以你正在取消引用空指针。这是错误的。你的程序崩溃了,所以不要再运行了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-30
      • 2021-12-13
      • 2016-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      相关资源
      最近更新 更多