首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >tcc中的空指针检测

tcc中的空指针检测
EN

Stack Overflow用户
提问于 2017-07-07 17:41:57
回答 3查看 126关注 0票数 0

我创建了一个非常简单的链接列表,并注意到我的代码在tcc filename.ctcc filename.c -run的输出方面存在差异:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct llist {
    struct llist *next;
    struct llist *last;
    struct llist *first;
    int value;
    int item;
    int *length;
};

struct llist *newList(int v){

    struct llist *l1 = malloc(sizeof(struct llist)); 
    l1 -> length = malloc(sizeof(int));
    *l1 -> length = 1;

    l1 -> value = v;    
    l1 -> item = 0;    
    l1 -> first = l1;

    return l1;
}

struct llist *appendList(struct llist *l1, int v){

    struct llist *l2 = malloc(sizeof(struct llist));

    l2 -> value = v;
    l2 -> last = l1;
    l2 -> first = l1 -> first;
    l2 -> length = l1 -> length; 
    *l2 -> length += 1; 
    l2 -> item = l1 -> item + 1;

    l1 -> next = l2;

    return l2;    
};

int main(){
    struct llist *list = newList(4);
    list = appendList(list, 6);
    list = appendList(list, 8);
    list = appendList(list, 10);

    list = list -> first;

    int end = 0;
    while(end==0){

        printf("VAL: %d\n", list -> value);

        if(list -> next == NULL){
            printf("END\n");
            end = 1;
        }else{

            list = list -> next;
        }
    }


    return 0;
}

对于使用tcc filename.c编译,然后运行它,它将产生我期望的输出:

代码语言:javascript
复制
VAL: 4
VAL: 6
VAL: 8
VAL: 10
END

这也是我在GCC和“嘎嘎”中得到的输出。

当我使用tcc filename.c -run时,我得到:

代码语言:javascript
复制
VAL: 4
VAL: 6
VAL: 8
VAL: 10
VAL: 27092544
VAL: 1489483720
VAL: 0
END

每次我运行时,最后一个数字总是为零,而另外两个值则不同。

我想出了一个解决方案,即在newList函数中添加l1 -> next = NULL;,在appendList函数中添加l2 -> next = NULL;

但我想知道为什么产量会有差异。编译器中有错误吗?或者我没有初始化指向NULL的指针,即使它在大多数编译器中都有效?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-07-07 17:54:56

我想出了一个解决方案,即在newList函数中添加l1 -> next = NULL;,在appendList函数中添加l2 -> next = NULL;。 但我想知道为什么产量会有差异。编译器中有错误吗?或者我没有初始化指向NULL的指针,即使它在大多数编译器中都有效?

如果没有分配指针值或导致指针被显式或隐式初始化(这与赋值不同),则访问指针的值是错误的。这样做会产生未定义的行为。然而,在某些情况下,程序碰巧表现出了您期望的行为,这是一个可能且看似合理的结果,但它并不能验证程序。

此外,您可能会发现,在更复杂的情况下,您的原始方法无法与您测试的其他编译器可靠地工作(但我只能对此做出概率声明,因为“未定义”)。

票数 1
EN

Stack Overflow用户

发布于 2017-07-07 17:52:39

通常调试程序时,调试器会初始化所有内容,但是在生产中没有初始化,因此下一个值不是null。

初始化下一个变量。

票数 0
EN

Stack Overflow用户

发布于 2017-07-07 19:26:45

函数calloc()返回指向初始化为零的字节序列的指针;相比之下,malloc()返回指向字节序列的指针,这些字节序列可能包含或不包含零。在某些平台上,这些字节总是在malloc()之后包含零;在其他平台上,至少有些字节永远不会包含。通常情况下,哪些字节将保持零,哪些字节不会保存,是不可预测的。

在大多数平台上,包括在过去几十年中创建的几乎所有平台上,清除指针对象的所有字节都会将指针设置为空。在记录此类行为的平台上,使用"calloc“而不是"malloc”为包含指针的结构创建空间是将其中的所有指针初始化为空的可靠方法。但是,如果使用"malloc“或"realloc”而不是"calloc“创建存储,则需要使用"memset”将所有字节设置为零,或者明确将其中包含的指针设置为NULL。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44976778

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档