【问题标题】:C - The variable 'p_prvy' is being used without being initializedC - 变量 'p_prvy' 正在被使用而没有被初始化
【发布时间】:2012-12-12 20:29:13
【问题描述】:

我正在尝试编译我的代码,但我无法编译它。我正在使用 VS 2010 并收到此消息:

“Tel_zoznam.exe”:已加载“C:\Windows\SysWOW64\msvcr100d.dll”,已加载符号。 运行时检查失败 #3 - 变量 'p_prvy' 未经初始化就被使用。

它停在p_prvy->next = NULL;

这是我的代码:

#include "stdafx.h"

#define MAX 31

typedef struct ZOZNAM{
    char meno[MAX];
    char priezvisko[MAX];
    char cislo1[MAX];
    char cislo2[MAX];
    char cislo3[MAX];
    struct ZOZNAM *next;
} ZOZNAM;

int main(void){
    char c;
    ZOZNAM * p_prvy;
ZOZNAM * p_akt;
    p_prvy->next = NULL;
    int z;
    p_akt=p_prvy;

    printf(" Pre pridanie kontaktu do zoznamu stlacte 'p'\n Pre vypis zoznamu zadajte 'v'\n Pre ukoncenie programu zadajte 'k'\n");
    z=pocet_zaznamov();
    printf("%d",z);
    while(1==1){
        scanf("%c",&c);

        switch(c){
            case 'p': vlozit(p_akt); break;
            case 'v': vypis(p_prvy); break;
            case 'n': nacitanie(p_akt); break;
        }
    }
    return 0;
}

【问题讨论】:

    标签: c++ c visual-studio-2010 pointers linked-list


    【解决方案1】:

    它几乎可以告诉您错误是什么:您在初始化之前使用了一个变量,因此您正在调用未定义的行为。

    ZOZNAM *p_prvy;
    p_prvy->next = NULL;
    

    是错误的,因为您尚未为 p_prvy 分配内存,但您取消引用它。为您的数据类型创建一个构造函数(并考虑您的设计)。

    【讨论】:

    • 如果使用c代码是c还是c++,是否可以设置构造函数?
    • @MehdiKaramosly 实际上没关系。当包装malloc()并为数据结构设置初始值的函数也称为构造函数时,可以用C编写OO风格的代码。
    • 我发现cs.rit.edu/~ats/books/ooc.pdf 是对 OO 风格 C 的相当全面的概述。
    • @Bracketworks:那是一本非常古老、非常好的书。强烈推荐。
    • @VladLazarenko 这就是我喜欢永恒原则的原因;能够很好地传达它们的资源本身就会变得永恒。
    【解决方案2】:

    在您的main() 函数中,您有以下p_prvy 变量声明:

    ZOZNAM * p_prvy;
    

    几乎在那之后,你说:

    p_prvy->next = NULL;
    

    这意味着您正在使用p_prvy 变量。但是,它没有被初始化,因此具有未指定的值。这称为Undefined Behavior,或简称为 UB。

    您需要做的是初始化该指针。例如,通过分配一些内存:

    ZOZNAM * p_prvy = (ZOZNAM *)malloc(sizeof(ZOZNAM));
    

    您也可以将其初始化为 NULL,但随后取消引用 NULL 将使您的进程停止。

    【讨论】:

    • 拜托,不要那样做,我的眼睛会吐出分配的内存!您还应该使用sizeof(*p_prvy) 而不是sizeof(ZOZNAM)
    • @H2CO3:我 100% 同意你的观点,但是,在这个问题上也有一个 #C++ 标签,所以我决定使用在这两种情况下都可以编译的东西。跨度>
    • 再一次,人们不会简单地将问题标记为C/C++,因为那不是一种语言:P :) 我明白你的理由,但是,sizeof(ZOZNAM) 仍然很危险(在 C++ 中也是如此)。
    • @H2CO3:我们公司的编码风格就是基于那个。我会说这还不错。所以我几乎在每个主题上都支持你,你是给我 +1 还是什么?
    • 我给你一个赞成票,因为你传播了良好的做法。
    猜你喜欢
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    相关资源
    最近更新 更多