【问题标题】:bytes were returned when we access the structure member and Segmentation fault occurs when printing structure variable address [duplicate]当我们访问结构成员时返回字节并且在打印结构变量地址时发生分段错误[重复]
【发布时间】:2019-04-22 13:21:21
【问题描述】:

我创建了一个struct 并为该结构分配了一个指针变量。当我尝试打印该变量的地址时,它会正确打印。在使用此pointer 结构变量为结构的成员之一赋值后,当我尝试打印pointer 变量的地址时,我得到了segmentation fault

#include <stdio.h>

typedef struct node {
char mem;
double mem2;
char mem3;
int mem4;
char mem5;
char mem6;
}NODE;
int main()
{
    NODE * m;
    printf("%u",&m);

    return 0;
}

我得到的输出为 3014616488。当我将变量分配给结构成员之一时,

#include <stdio.h>

typedef struct node {
char mem;
double mem2;
char mem3;
int mem4;
char mem5;
char mem6;
}NODE;
int main()
{
   NODE * m;
   m->mem3 = 'A';
   printf("%u",&m);

   return 0;
}

我遇到了分段错误。当我喜欢这个时

#include <stdio.h>

typedef struct node {
char mem;
double mem2;
char mem3;
int mem4;
char mem5;
char mem6;
}NODE;
int main()
{
    NODE * m;
    printf("%u",&m->mem3);

    return 0;
}

我得到 16 作为输出。我不知道16是怎么来的。它真的在我的脑海里挣扎。请任何人帮助我了解到底发生了什么。提前致谢

【问题讨论】:

  • m 是一个指针,但你永远不会让它指向任何地方。所以当你取消引用它(通过m-&gt;mem3)你有undefined behavior。未初始化的局部变量将有一个不确定(并且看似随机)的值。
  • 另外,当打印带有printf 的指针时,你应该使用"%p",否则你也会有未定义的行为。并且指针真的应该被强制转换为void * 才能正确。最后,不要忘记&amp;m 是指向变量m 的指针(并且具有NODE ** 类型),它不是m 指向的位置(如果没有地址,那将是简单的m运算符)。
  • 关于代码的第二个版本:变量m 从未初始化为结构节点的实例。而是声明了指向此类结构的指针的实例。但是该指针永远不会设置为指向结构节点的实例。所以声明:m-&gt;mem3 = 'A'; 是未定义的行为,任何事情都可能发生。注意:贴出的代码的三个版本都有相同的问题,导致未定义的行为
  • 编译时,始终启用警告,然后修复这些警告。 (对于gcc,至少使用:-Wall -Wextra -Werror -Wconversion -pedantic -std=gnu11)注意:其他编译器使用不同的选项来产生相同的东西。
  • 第三版代码不是未定义的,它是有效的。但它在打印 mem3 变量的起始字节。我不知道为什么。请解释一下。 @user3629249

标签: c pointers memory-management segmentation-fault structure


【解决方案1】:

因为它没有分配任何内存

NODE * m = malloc(sizeof(NODE));

// Do stuffs

free(m);

所以试试这个:

int main()
{
    NODE * m = malloc(sizeof(NODE));

    m->mem3 = 'A';
    printf("%u",&m->mem3);

    free(m);

    return 0;
}

注意:

Int cc++ 如果您声明 pointer,则为 pointer 保留一些内存(通常在 stack 上)。无论如何,指针没有被初始化,这意味着它指向与最后在相应内存位置中的地址相对应的地址。 (这就是code 的第一部分起作用的原因)。

【讨论】:

  • 是的,干得好。您还可以使用取消引用指针来始终提供正确的类型大小,例如malloc (sizeof *m);
  • 第三版代码不是未定义的,它是有效的。但它在打印 mem3 变量的起始字节。我不知道为什么。请解释一下
  • @Aadhithaneswaramoorthy 哪个第三版?每件事都很明显......
  • @Mohammadreza Panahi #include typedef struct node { char mem;双内存2; char mem3; int mem4; char mem5; char mem6; }节点; int main() { 节点 * m; m->mem3 = 'A'; printf("%u",&m->mem3);返回0;这会产生正确的输出并返回 mem3 16 的起始字节数。我有什么解释它是如何发生的
  • @ Mohammadreza Panahi 请解释一下我在许多编译器中尝试过的第三段代码,我得到了相同的输出,看来这是一个有效的非未定义行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 2021-12-06
  • 2019-07-28
  • 1970-01-01
  • 2019-04-22
  • 1970-01-01
相关资源
最近更新 更多