【问题标题】:how to acess value of a extern variable within multiple header files如何在多个头文件中访问外部变量的值
【发布时间】:2021-03-08 06:51:28
【问题描述】:

我有 2 个头文件,login.h 和 inmenu.h。 login.h 也包含了 inmenu.h。

现在 login.h 定义了一个外部变量 extern char *password_login,它位于 var.h 头文件中

printf("Enter the password: \n");
char *password_login = (char *)calloc(MAX, sizeof(char));
scanf("%1000s", password_login);

之后,当我从 inmenu 头文件调用 inmenu() 函数并尝试访问 password_login 值

char *tmpsqluppass = concatsqluppass(password_login, newpass);

这没有说明对 password_login 的未定义引用

/usr/bin/ld: /tmp/ccKZpQvi.o: 警告:针对password_login' in read-only section .text'的重定位 /usr/bin/ld: /tmp/ccKZpQvi.o: 在函数inmenu': /home/legacy/Documents/project/src/../include/inmenu.h:27: undefined reference to password_login' /usr/bin/ld:警告:在 PIE 中创建 DT_TEXTREL collect2:错误:ld 返回 1 个退出状态

当我在 inmenu.h 中重新声明 char *password_login 时,此错误消失

但是随后发生分段错误,因为 login.h 中 password_login 的原始值丢失并且 password_login 指向 0x0 内存地址,我使用 strcat() 将 password_login 连接到另一个字符串。

如何在登录时保留inmenu中password_login指针的值。

这是 concatsqluppass 函数

char *concatsqluppass(char *tmppass, char *tmppassnew)
{
    char *sql;
    sql = (char *)calloc(MAX, sizeof(char));
    strcat(sql, "update user_list set encpass = '");
    strcat(sql, tmppassnew);
    strcat(sql, "'");
    strcat(sql, " where encpass = '");
    strcat(sql, tmppass);
    strcat(sql, "'");
    strcat(sql, "\0");
    printf("query to be passed, \"%s\"", sql);
    return sql;
}

【问题讨论】:

    标签: c segmentation-fault linker-errors header-files


    【解决方案1】:

    声明变量和定义变量是有区别的。一个变量至少可以声明一次(但允许更多)。一个变量只能定义一次。 当您执行extern int x 时,您正在声明一个变量。这表示“这个变量存在。我没做到,别人做到了。只是让你知道它的存在“。 当您执行 int x 时,您正在声明 定义一个变量。这表示“我刚刚制作了这个变量。我为它创造了记忆。它存在。如果你能看到这个语句你可以使用这个变量”

    如果您将定义 (int x) 放在标题中,您可能会多次定义一个变量,因为多个文件将 #include 该文件。 这就是为什么您应该将定义 (int x) 放在 cpp 文件中,因为没有人应该将 #include 放在 cpp 中。如果其他文件也需要使用该变量,也可以在头文件中声明(extern int x)。

    这样做,您可以将extern char *password_login 放入任意数量的标题中,并在这些文件上使用变量。

    【讨论】:

    • 嗯,我明白了。如果我在包含标题的主 c 文件(char *password_login;)中定义变量,那么我应该只声明“extern char *password_login;”在标题中?感谢您的澄清。
    • int x; 在函数外部是 C 中的暂定定义,如果有多个暂定定义到实现,C 标准会发生什么。直到最近,GCC 根据长期存在的 Unix 工具行为合并了暂定定义。它仍然可以使用-fcommon 开关进行选择。
    【解决方案2】:

    在登录目标文件中定义密码,并在 imenu 目标文件中定义相同的变量

    extern char * password_login
    ...
    ...
    function(password_login,...);
    

    确保使用目标文件而不是在头文件中编写代码。

    【讨论】:

    • 我应该将登录和菜单编译为目标文件并在之后链接它们吗?
    猜你喜欢
    • 2021-09-09
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 2022-08-04
    • 1970-01-01
    相关资源
    最近更新 更多