我今天遇到了一个奇怪的问题。快速浏览一下这个简化的代码片段:
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;
}
当我编译这个程序时,没有发生错误,但是当我运行编译文件时,它不会向commmand-line打印任何内容(我在Windows机器上使用PuTTy)。删除行LINE A
和LINE B
后会变得甚至奇怪,然后可以打印LINE C.
简而言之,LINE A之后的任何内容都无法打印出来(或执行?)。
我不知道我的代码是否有任何问题。
答案 0 :(得分:4)
它没有打印任何东西的原因是因为它崩溃了:
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;
}
答案 1 :(得分:4)
在第二行,您将取消引用NULL
指针,这会导致未定义的行为:
INDEX *ind = NULL;
ind->nTerms = 5;
return ind;
您需要使ind
指向非本地内存,即使用malloc
从堆中分配,或将其设置为指向具有全局生存期的变量:
INDEX *ind = malloc(sizeof(INDEX));
if (ind != NULL)
ind->nTerms = 5;
return ind;
在这种情况下,释放返回的struct(并且如果它为NULL则不解除引用)的责任被委托给调用者。
请注意,如果要将ind
设置为指向本地声明的变量并返回它,则只要调用者尝试取消引用指针,就会发生UB,因为在函数终止后将恢复堆栈。 / p>
答案 2 :(得分:1)
您的问题似乎在buildIndex
中INDEX *buildIndex(char *termsfile, char *dirs[], int n, OPTIONS opts)
{
INDEX *ind = NULL;
ind->nTerms = 5;
return ind;
}
如您所见,您将ind
设置为NULL
,然后尝试立即引用。那是未定义的行为,所以接下来就会发生任何事情。
答案 3 :(得分:0)
你调用包含这两行的函数buildIndex
。
INDEX * ind = NULL; ind-> nTerms = 5;
所以你要取消引用空指针。这是错误的。你的程序崩溃了,所以不要再运行了。